From d6a13348978418db153aaae2413dff581715bb34 Mon Sep 17 00:00:00 2001 From: Ravi Aggarwal Date: Sat, 12 Oct 2019 23:16:58 +0530 Subject: [PATCH 1/2] Added support for Code128, Aztec and PDF417 --- QRIO/QRIO.swift | 90 +++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/QRIO/QRIO.swift b/QRIO/QRIO.swift index 5672fe8..a6bba13 100644 --- a/QRIO/QRIO.swift +++ b/QRIO/QRIO.swift @@ -16,8 +16,14 @@ open class QRInput: NSObject, AVCaptureMetadataOutputObjectsDelegate { open var imageScanCompletionBlock: ((_ string: String) -> ())? - - open func scanForQRImage(previewIn previewContainer: UIView? = nil, rectOfInterest: CGRect? = nil, completion: @escaping ((_ string: String) -> ())) { + private let barCodeMetaType: [AVMetadataObject.ObjectType] = [ + .qr, + .code128, + .pdf417, + .aztec + ] + + open func scanForBarcodeImage(previewIn previewContainer: UIView? = nil, rectOfInterest: CGRect? = nil, completion: @escaping ((_ string: String) -> ())) { let session = AVCaptureSession() self.session = session guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return } @@ -54,16 +60,16 @@ open class QRInput: NSObject, AVCaptureMetadataOutputObjectsDelegate { } open func metadataOutput(_ captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { - var QRCode: String? - for metadata in metadataObjects { - if metadata.type == AVMetadataObject.ObjectType.qr { - QRCode = (metadata as! AVMetadataMachineReadableCodeObject).stringValue - } - } - if let code = QRCode { - imageScanCompletionBlock?(code) - } - } + var QRCode: String? + for metadata in metadataObjects { + if barCodeMetaType.contains(metadata.type) { + QRCode = (metadata as! AVMetadataMachineReadableCodeObject).stringValue + } + } + if let code = QRCode { + imageScanCompletionBlock?(code) + } + } open func finish() { imageScanCompletionBlock = nil @@ -81,28 +87,48 @@ open class QRInput: NSObject, AVCaptureMetadataOutputObjectsDelegate { } } +public enum BarCode: String { + case qr = "CIQRCodeGenerator" + case code128 = "CICode128BarcodeGenerator" + case pdf417 = "CIPDF417BarcodeGenerator" + case aztec = "CIAztecCodeGenerator" +} public extension UIImage { + static func barCodeFor(string: String, containingViewSize: CGSize? = nil, correctionLevel: String = "L", type: BarCode = .qr) -> UIImage? { + var strData: Data? + + switch type { + case .aztec, .pdf417, .qr: + strData = string.data(using: String.Encoding.isoLatin1) + case .code128: + strData = string.data(using: String.Encoding.ascii) + } + + guard let filter = CIFilter(name: type.rawValue), let stringData = strData else { return nil } + + filter.setValue(stringData, forKey: "inputMessage") + filter.setValue(correctionLevel, forKey: "inputCorrectionLevel") + + guard let resultImage = filter.outputImage else { return nil } + + var scaleX = resultImage.extent.size.width + var scaleY = resultImage.extent.size.height + if let size = containingViewSize { + scaleX = size.width / resultImage.extent.size.width + scaleY = size.height / resultImage.extent.size.height + } + + let qrImage = resultImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY)) + let context = CIContext() + if let tempImage: CGImage = context.createCGImage(qrImage, from: qrImage.extent) { + return UIImage(cgImage: tempImage) + } + + return nil + } + static func QRImageFrom(string: String, containingViewSize: CGSize? = nil, correctionLevel: String = "L") -> UIImage? { - let stringData = string.data(using: String.Encoding.isoLatin1) - let filter = CIFilter(name: "CIQRCodeGenerator") - filter?.setValue(stringData, forKey: "inputMessage") - filter?.setValue(correctionLevel, forKey: "inputCorrectionLevel") - - guard let resultImage = filter?.outputImage else { return nil } - - var scaleX = resultImage.extent.size.width - var scaleY = resultImage.extent.size.height - if let size = containingViewSize { - scaleX = size.width / resultImage.extent.size.width - scaleY = size.height / resultImage.extent.size.height - } - - let qrImage = resultImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY)) - let context = CIContext() - if let tempImage: CGImage = context.createCGImage(qrImage, from: qrImage.extent) { - return UIImage(cgImage: tempImage) - } - return nil + return Self.barCodeFor(string: string, containingViewSize: containingViewSize, correctionLevel: correctionLevel, type: .qr) } } From 778fbd40e3ebca92697b45dfbdded23ef99023f5 Mon Sep 17 00:00:00 2001 From: Ravi Aggarwal Date: Sun, 13 Oct 2019 00:43:29 +0530 Subject: [PATCH 2/2] refactoring barcode image generation methods --- QRIO/QRIO.swift | 63 +++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/QRIO/QRIO.swift b/QRIO/QRIO.swift index a6bba13..5afcbab 100644 --- a/QRIO/QRIO.swift +++ b/QRIO/QRIO.swift @@ -87,29 +87,11 @@ open class QRInput: NSObject, AVCaptureMetadataOutputObjectsDelegate { } } -public enum BarCode: String { - case qr = "CIQRCodeGenerator" - case code128 = "CICode128BarcodeGenerator" - case pdf417 = "CIPDF417BarcodeGenerator" - case aztec = "CIAztecCodeGenerator" -} - public extension UIImage { - static func barCodeFor(string: String, containingViewSize: CGSize? = nil, correctionLevel: String = "L", type: BarCode = .qr) -> UIImage? { - var strData: Data? - - switch type { - case .aztec, .pdf417, .qr: - strData = string.data(using: String.Encoding.isoLatin1) - case .code128: - strData = string.data(using: String.Encoding.ascii) - } - - guard let filter = CIFilter(name: type.rawValue), let stringData = strData else { return nil } + private static func barcode(from data: Data, filter: CIFilter, containingViewSize: CGSize? = nil) -> UIImage? { + + filter.setValue(data, forKey: "inputMessage") - filter.setValue(stringData, forKey: "inputMessage") - filter.setValue(correctionLevel, forKey: "inputCorrectionLevel") - guard let resultImage = filter.outputImage else { return nil } var scaleX = resultImage.extent.size.width @@ -127,8 +109,39 @@ public extension UIImage { return nil } - - static func QRImageFrom(string: String, containingViewSize: CGSize? = nil, correctionLevel: String = "L") -> UIImage? { - return Self.barCodeFor(string: string, containingViewSize: containingViewSize, correctionLevel: correctionLevel, type: .qr) - } + + static func pdf417CodeFrom(string: String, containingViewSize: CGSize? = nil, correctionLevel: NSNumber = NSNumber(integerLiteral: 0)) -> UIImage? { + + guard let stringData = string.data(using: .isoLatin1), + let filter = CIFilter(name: "CIPDF417BarcodeGenerator") else { return nil } + + filter.setValue(correctionLevel, forKey: "inputCorrectionLevel") + return barcode(from: stringData, filter: filter, containingViewSize: containingViewSize) + } + + static func barcode128From(string: String, containingViewSize: CGSize? = nil) -> UIImage? { + + guard let stringData = string.data(using: .ascii), + let filter = CIFilter(name: "CICode128BarcodeGenerator") else { return nil } + + return barcode(from: stringData, filter: filter, containingViewSize: containingViewSize) + } + + static func aztecCodeFrom(string: String, containingViewSize: CGSize? = nil, correctionLevel: NSNumber = NSNumber(integerLiteral: 23)) -> UIImage? { + + guard let stringData = string.data(using: .isoLatin1), + let filter = CIFilter(name: "CIAztecCodeGenerator") else { return nil } + + filter.setValue(correctionLevel, forKey: "inputCorrectionLevel") + return barcode(from: stringData, filter: filter, containingViewSize: containingViewSize) + } + + static func QRImageFrom(string: String, containingViewSize: CGSize? = nil, correctionLevel: String = "L") -> UIImage? { + + guard let stringData = string.data(using: .isoLatin1), + let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil } + + filter.setValue(correctionLevel, forKey: "inputCorrectionLevel") + return barcode(from: stringData, filter: filter, containingViewSize: containingViewSize) + } }