如何从Swift中的字符串生成条形码?

时间:2015-02-16 13:14:01

标签: ios swift barcode core-image

我是一名新的iOS开发人员。我想知道如何在Swift中生成条形码。

我已经有了代码,有多种资源可以从哪里学习如何阅读条形码,但我没有找到任何关于从字符串生成代码的内容。

非常感谢!

P.S。我知道有一个类似的问题,但它适用于Objective-C。我不知道Obj-C,我发现它很难来自.NET。

4 个答案:

答案 0 :(得分:71)

你可以使用CoreImage(import CoreImage)过滤器来做到这一点!

class Barcode {
    class func fromString(string : String) -> UIImage? {
         let data = string.data(using: .ascii)
         if let filter = CIFilter(name: "CICode128BarcodeGenerator") {
              filter.setValue(data, forKey: "inputMessage")
              if let outputCIImage = filter.outputImage {
                   return UIImage(ciImage: outputCIImage)
              }
         }
         return nil
    }
}

let img = Barcode.fromString("whateva")

根据docs

  

根据输出数据生成表示输入数据的输出图像   ISO / IEC 15417:2007标准。每个模块的宽度(垂直线)   输出图像中条形码的一个像素。的高度   条形码是32像素。要从字符串或URL创建条形码,   使用NSASCIIStringEncoding字符串将其转换为NSData对象   编码

答案 1 :(得分:15)

改进代码:

  • 条形码缩放
  • 设置条形码图像边距
  • 将UIImage转换为NSData(出于某种原因,上述代码无法实现)。
  • 共享条形码图片时可能会失败(可能是因为同样的错误)

Swift 3

func generateBarcode(from string: String) -> UIImage? {

    let data = string.data(using: String.Encoding.ascii)

    if let filter = CIFilter(name: "CICode128BarcodeGenerator") {
        filter.setDefaults()
        //Margin
        filter.setValue(7.00, forKey: "inputQuietSpace")
        filter.setValue(data, forKey: "inputMessage")
        //Scaling
        let transform = CGAffineTransform(scaleX: 3, y: 3)

        if let output = filter.outputImage?.applying(transform) {
            let context:CIContext = CIContext.init(options: nil)
            let cgImage:CGImage = context.createCGImage(output, from: output.extent)!
            let rawImage:UIImage = UIImage.init(cgImage: cgImage)

            //Refinement code to allow conversion to NSData or share UIImage. Code here:
            //http://stackoverflow.com/questions/2240395/uiimage-created-from-cgimageref-fails-with-uiimagepngrepresentation
            let cgimage: CGImage = (rawImage.cgImage)!
            let cropZone = CGRect(x: 0, y: 0, width: Int(rawImage.size.width), height: Int(rawImage.size.height))
            let cWidth: size_t  = size_t(cropZone.size.width)
            let cHeight: size_t  = size_t(cropZone.size.height)
            let bitsPerComponent: size_t = cgimage.bitsPerComponent
            //THE OPERATIONS ORDER COULD BE FLIPPED, ALTHOUGH, IT DOESN'T AFFECT THE RESULT
            let bytesPerRow = (cgimage.bytesPerRow) / (cgimage.width  * cWidth)

            let context2: CGContext = CGContext(data: nil, width: cWidth, height: cHeight, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: cgimage.bitmapInfo.rawValue)!

            context2.draw(cgimage, in: cropZone)

            let result: CGImage  = context2.makeImage()!
            let finalImage = UIImage(cgImage: result)

            return finalImage

        }
    }

    return nil
}

答案 2 :(得分:7)

如果您的部署目标至少是iOS 8,则可以使用Core Image。这是我的BarcodeGenerator类(您需要import CoreImage):

class BarcodeGenerator {
    enum Descriptor: String {
        case code128 = "CICode128BarcodeGenerator"
        case pdf417 = "CIPDF417BarcodeGenerator"
        case aztec = "CIAztecCodeGenerator"
        case qr = "CIQRCodeGenerator"
    }

    class func generate(from string: String, 
                         descriptor: Descriptor, 
                               size: CGSize) -> CIImage? {
        let filterName = descriptor.rawValue

        guard let data = string.data(using: .ascii),
            let filter = CIFilter(name: filterName) else {
                return nil
        }

        filter.setValue(data, forKey: "inputMessage")

        guard let image = filter.outputImage else {
            return nil
        }

        let imageSize = image.extent.size

        let transform = CGAffineTransform(scaleX: size.width / imageSize.width,
                                               y: size.height / imageSize.height)
        let scaledImage = image.transformed(by: transform)

        return scaledImage
    }
}

可以像这样使用

BarcodeGenerator.generate(from: "barcode-string", 
                     symbology: .code128, 
                          size: CGSize(width: 800, height: 300))

答案 3 :(得分:0)

像这样使用

func createBarcodeFromString(barcode:String)->UIImage?{

    let data = self.data(using: .isoLatin1)
    guard let filter = CIFilter(name: "CICode128BarcodeGenerator") else {
        return nil
    }
    filter.setValue(data, forKey: "inputMessage")
    filter.setValue(7.0, forKey:"inputQuietSpace")
    guard var ciImage = filter.outputImage else {
        return nil
    }

    let imageSize = ciImage.extent.integral
    let outputSize = CGSize(width:320, height: 60)
    ciImage = ciImage.transformed(by:CGAffineTransform(scaleX: outputSize.width/imageSize.width, y: outputSize.height/imageSize.height))

    let image = convertCIImageToUIImage(ciimage: ciImage)
    return image
}

func convertCIImageToUIImage(ciimage:CIImage)->UIImage{
    let context:CIContext = CIContext.init(options: nil)
    let cgImage:CGImage = context.createCGImage(ciimage, from: ciimage.extent)!
    let image:UIImage = UIImage.init(cgImage: cgImage)
    return image
}