Làm cách nào tôi có thể quét mã vạch trên iPhone và / hoặc iPad?
Làm cách nào tôi có thể quét mã vạch trên iPhone và / hoặc iPad?
Câu trả lời:
Chúng tôi đã sản xuất ứng dụng 'Mã vạch' cho iPhone. Nó có thể giải mã mã QR. Mã nguồn có sẵn từ dự án zxing ; cụ thể, bạn muốn xem qua ứng dụng khách iPhone và cổng C ++ một phần của thư viện lõi . Cổng này hơi cũ, từ bản phát hành 0,9 của mã Java, nhưng vẫn hoạt động tốt.
Nếu bạn cần quét các định dạng khác, như định dạng 1D, bạn có thể tiếp tục chuyển mã Java trong dự án này sang C ++.
EDIT: Mã vạch và iphone
mã trong dự án đã nghỉ hưu vào khoảng đầu năm 2014.
Hãy xem ZBar đọc Mã QR và mã ECN / ISBN và có sẵn theo giấy phép LGPL v2.
Như với việc phát hành, iOS7
bạn không còn cần phải sử dụng một khung hoặc thư viện bên ngoài. Hệ sinh thái iOS với AVFoundation hiện hỗ trợ quét hầu hết mọi mã từ QR qua EAN đến UPC.
Chỉ cần xem qua Tech Note và hướng dẫn lập trình AVFoundation. AVMetadataObjectTypeQRCode
là bạn của bạn.
Dưới đây là một hướng dẫn hay cho thấy nó từng bước: Thư viện quét mã QR iPhone iOS7
Chỉ là một ví dụ nhỏ về cách thiết lập nó:
#pragma mark -
#pragma mark AVFoundationScanSetup
- (void) setupScanner;
{
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
self.session = [[AVCaptureSession alloc] init];
self.output = [[AVCaptureMetadataOutput alloc] init];
[self.session addOutput:self.output];
[self.session addInput:self.input];
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.preview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
AVCaptureConnection *con = self.preview.connection;
con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
[self.view.layer insertSublayer:self.preview atIndex:0];
}
startRunning
vào phiên để có được mã trên để làm việc trong trường hợp giúp được bất cứ ai :)
Camera của iPhone 4 còn hơn cả capabale khi làm mã vạch. Thư viện mã vạch vượt qua ngựa vằn có một ngã ba trên github zxing-iphone . Đó là nguồn mở.
liteqr là "Trình đọc QR Lite trong Objective C được chuyển từ zxing" trên github và có hỗ trợ Xcode 4.
Có hai thư viện chính:
ZXing một thư viện được viết bằng Java và sau đó được chuyển sang Objective C / C ++ (chỉ mã QR). Và một cổng khác đến ObjC đã được thực hiện, bởi TheLevelUp: ZXingObjC
ZBar một phần mềm mã nguồn mở để đọc mã vạch, dựa trên C.
Theo thí nghiệm của tôi, ZBar chính xác và nhanh hơn nhiều so với ZXing, ít nhất là trên iPhone.
HƯỚNG DẪN : Thêm trình đọc mã vạch vào ứng dụng iPhone , trỏ đến SDK iPhone ZBar , có vẻ hữu ích ( từ một chủ đề khác ).
Bạn có thể tìm một giải pháp iOS gốc khác bằng Swift 4 và Xcode 9 ở bên dưới. AVFoundation
Khung bản địa được sử dụng với trong giải pháp này.
Phần đầu tiên là lớp con UIViewController
có chức năng thiết lập và xử lý liên quan choAVCaptureSession
.
import UIKit
import AVFoundation
class BarCodeScannerViewController: UIViewController {
let captureSession = AVCaptureSession()
var videoPreviewLayer: AVCaptureVideoPreviewLayer!
var initialized = false
let barCodeTypes = [AVMetadataObject.ObjectType.upce,
AVMetadataObject.ObjectType.code39,
AVMetadataObject.ObjectType.code39Mod43,
AVMetadataObject.ObjectType.code93,
AVMetadataObject.ObjectType.code128,
AVMetadataObject.ObjectType.ean8,
AVMetadataObject.ObjectType.ean13,
AVMetadataObject.ObjectType.aztec,
AVMetadataObject.ObjectType.pdf417,
AVMetadataObject.ObjectType.itf14,
AVMetadataObject.ObjectType.dataMatrix,
AVMetadataObject.ObjectType.interleaved2of5,
AVMetadataObject.ObjectType.qr]
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupCapture()
// set observer for UIApplicationWillEnterForeground, so we know when to start the capture session again
NotificationCenter.default.addObserver(self,
selector: #selector(willEnterForeground),
name: .UIApplicationWillEnterForeground,
object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// this view is no longer topmost in the app, so we don't need a callback if we return to the app.
NotificationCenter.default.removeObserver(self,
name: .UIApplicationWillEnterForeground,
object: nil)
}
// This is called when we return from another app to the scanner view
@objc func willEnterForeground() {
setupCapture()
}
func setupCapture() {
var success = false
var accessDenied = false
var accessRequested = false
let authorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
if authorizationStatus == .notDetermined {
// permission dialog not yet presented, request authorization
accessRequested = true
AVCaptureDevice.requestAccess(for: .video,
completionHandler: { (granted:Bool) -> Void in
self.setupCapture();
})
return
}
if authorizationStatus == .restricted || authorizationStatus == .denied {
accessDenied = true
}
if initialized {
success = true
} else {
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera,
.builtInTelephotoCamera,
.builtInDualCamera],
mediaType: .video,
position: .unspecified)
if let captureDevice = deviceDiscoverySession.devices.first {
do {
let videoInput = try AVCaptureDeviceInput(device: captureDevice)
captureSession.addInput(videoInput)
success = true
} catch {
NSLog("Cannot construct capture device input")
}
} else {
NSLog("Cannot get capture device")
}
}
if success {
DispatchQueue.global().async {
self.captureSession.startRunning()
DispatchQueue.main.async {
let captureMetadataOutput = AVCaptureMetadataOutput()
self.captureSession.addOutput(captureMetadataOutput)
let newSerialQueue = DispatchQueue(label: "barCodeScannerQueue") // in iOS 11 you can use main queue
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: newSerialQueue)
captureMetadataOutput.metadataObjectTypes = self.barCodeTypes
self.videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
self.videoPreviewLayer.videoGravity = .resizeAspectFill
self.videoPreviewLayer.frame = self.view.layer.bounds
self.view.layer.addSublayer(self.videoPreviewLayer)
}
}
initialized = true
} else {
// Only show a dialog if we have not just asked the user for permission to use the camera. Asking permission
// sends its own dialog to th user
if !accessRequested {
// Generic message if we cannot figure out why we cannot establish a camera session
var message = "Cannot access camera to scan bar codes"
#if (arch(i386) || arch(x86_64)) && (!os(macOS))
message = "You are running on the simulator, which does not hae a camera device. Try this on a real iOS device."
#endif
if accessDenied {
message = "You have denied this app permission to access to the camera. Please go to settings and enable camera access permission to be able to scan bar codes"
}
let alertPrompt = UIAlertController(title: "Cannot access camera", message: message, preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
self.navigationController?.popViewController(animated: true)
})
alertPrompt.addAction(confirmAction)
self.present(alertPrompt, animated: true, completion: nil)
}
}
}
func handleCapturedOutput(metadataObjects: [AVMetadataObject]) {
if metadataObjects.count == 0 {
return
}
guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject else {
return
}
if barCodeTypes.contains(metadataObject.type) {
if let metaDataString = metadataObject.stringValue {
captureSession.stopRunning()
displayResult(code: metaDataString)
return
}
}
}
func displayResult(code: String) {
let alertPrompt = UIAlertController(title: "Bar code detected", message: code, preferredStyle: .alert)
if let url = URL(string: code) {
let confirmAction = UIAlertAction(title: "Launch URL", style: .default, handler: { (action) -> Void in
UIApplication.shared.open(url, options: [:], completionHandler: { (result) in
if result {
NSLog("opened url")
} else {
let alertPrompt = UIAlertController(title: "Cannot open url", message: nil, preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
})
alertPrompt.addAction(confirmAction)
self.present(alertPrompt, animated: true, completion: {
self.setupCapture()
})
}
})
})
alertPrompt.addAction(confirmAction)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in
self.setupCapture()
})
alertPrompt.addAction(cancelAction)
present(alertPrompt, animated: true, completion: nil)
}
}
Phần thứ hai là phần mở rộng của UIViewController
lớp con của chúng tôi choAVCaptureMetadataOutputObjectsDelegate
, nơi chúng tôi bắt được các kết quả đầu ra.
extension BarCodeScannerViewController: AVCaptureMetadataOutputObjectsDelegate {
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
handleCapturedOutput(metadataObjects: metadataObjects)
}
}
Cập nhật cho Swift 4.2
.UIApplicationWillEnterForeground
thay đổi như UIApplication.willEnterForegroundNotification
.
metadataObjects
bên trong hàm handleCapturedOutput .
Không chắc chắn nếu điều này sẽ giúp nhưng đây là một liên kết đến thư viện Mã QR nguồn mở . Như bạn có thể thấy một vài người đã sử dụng điều này để tạo ứng dụng cho iphone.
Wikipedia có một bài viết giải thích Mã QR là gì . Theo tôi, Mã QR phù hợp với mục đích hơn nhiều so với mã vạch tiêu chuẩn mà iphone quan tâm vì nó được thiết kế cho loại triển khai này.
Nếu hỗ trợ cho iPad 2 hoặc iPod Touch là quan trọng cho ứng dụng của bạn, tôi sẽ chọn SDK máy quét mã vạch có thể giải mã mã vạch trong hình ảnh mờ, chẳng hạn như SDK máy quét mã vạch Scandit của chúng tôi cho iOS và Android. Giải mã hình ảnh mã vạch mờ cũng hữu ích trên điện thoại có camera tự động lấy nét vì người dùng không phải chờ lấy nét tự động để khởi động.
Scandit đi kèm với gói giá cộng đồng miễn phí và cũng có API sản phẩm giúp dễ dàng chuyển đổi số mã vạch thành tên sản phẩm.
(Tuyên bố miễn trừ trách nhiệm: Tôi là người đồng sáng lập của Scandit)
Bạn có thể xem Mã nguồn đọc dữ liệu iPhone DataMatrix của Stefan Hafaler ( dự án Google Code ; bài đăng trên blog được lưu trữ ) nếu nó vẫn có sẵn.
Vấn đề với camera iPhone là các model đầu tiên (trong đó có hàng tấn đang sử dụng) có camera lấy nét cố định không thể chụp ảnh lấy nét trong khoảng cách dưới 2ft. Hình ảnh bị mờ và bị bóp méo và nếu được chụp từ khoảng cách lớn hơn thì không có đủ chi tiết / thông tin từ mã vạch.
Một số công ty đã phát triển các ứng dụng iPhone có thể hỗ trợ cho việc đó bằng cách sử dụng các công nghệ làm mờ tiên tiến. Những ứng dụng bạn có thể tìm thấy trên cửa hàng ứng dụng Apple: pic2shop, RedLaser và ShopSavvy. Tất cả các công ty đã thông báo rằng họ cũng có sẵn SDK - một số cho các điều khoản miễn phí hoặc rất ưu đãi, hãy kiểm tra xem chúng có tồn tại không.
với Swift 5 thật đơn giản và siêu nhanh !!
Bạn chỉ cần thêm vỏ ca cao "BarcodeScanner" ở đây là mã đầy đủ
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'Simple BarcodeScanner'
do
pod 'BarcodeScanner'
end
Đảm bảo thêm quyền Camera trong tệp .plist của bạn
<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>
Và thêm Trình quét và xử lý kết quả trong ViewContoder của bạn theo cách này
import UIKit
import BarcodeScanner
class ViewController: UIViewController, BarcodeScannerCodeDelegate, BarcodeScannerErrorDelegate, BarcodeScannerDismissalDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let viewController = BarcodeScannerViewController()
viewController.codeDelegate = self
viewController.errorDelegate = self
viewController.dismissalDelegate = self
present(viewController, animated: true, completion: nil)
}
func scanner(_ controller: BarcodeScannerViewController, didCaptureCode code: String, type: String) {
print("Product's Bar code is :", code)
controller.dismiss(animated: true, completion: nil)
}
func scanner(_ controller: BarcodeScannerViewController, didReceiveError error: Error) {
print(error)
}
func scannerDidDismiss(_ controller: BarcodeScannerViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
Tuy nhiên và bất kỳ câu hỏi hoặc thách thức, vui lòng kiểm tra ứng dụng mẫu ở đây với mã nguồn đầy đủ
Đối với trình quét mã vạch iOS 7 gốc, hãy xem dự án của tôi trên GitHub:
Tôi tin rằng điều này có thể được thực hiện bằng AVFramework, đây là mã mẫu để làm điều này
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate
{
@IBOutlet weak var lblQRCodeResult: UILabel!
@IBOutlet weak var lblQRCodeLabel: UILabel!
var objCaptureSession:AVCaptureSession?
var objCaptureVideoPreviewLayer:AVCaptureVideoPreviewLayer?
var vwQRCode:UIView?
override func viewDidLoad() {
super.viewDidLoad()
self.configureVideoCapture()
self.addVideoPreviewLayer()
self.initializeQRView()
}
func configureVideoCapture() {
let objCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
var error:NSError?
let objCaptureDeviceInput: AnyObject!
do {
objCaptureDeviceInput = try AVCaptureDeviceInput(device: objCaptureDevice) as AVCaptureDeviceInput
} catch let error1 as NSError {
error = error1
objCaptureDeviceInput = nil
}
objCaptureSession = AVCaptureSession()
objCaptureSession?.addInput(objCaptureDeviceInput as! AVCaptureInput)
let objCaptureMetadataOutput = AVCaptureMetadataOutput()
objCaptureSession?.addOutput(objCaptureMetadataOutput)
objCaptureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
objCaptureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
}
func addVideoPreviewLayer() {
objCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: objCaptureSession)
objCaptureVideoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
objCaptureVideoPreviewLayer?.frame = view.layer.bounds
self.view.layer.addSublayer(objCaptureVideoPreviewLayer!)
objCaptureSession?.startRunning()
self.view.bringSubviewToFront(lblQRCodeResult)
self.view.bringSubviewToFront(lblQRCodeLabel)
}
func initializeQRView() {
vwQRCode = UIView()
vwQRCode?.layer.borderColor = UIColor.redColor().CGColor
vwQRCode?.layer.borderWidth = 5
self.view.addSubview(vwQRCode!)
self.view.bringSubviewToFront(vwQRCode!)
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
if metadataObjects == nil || metadataObjects.count == 0 {
vwQRCode?.frame = CGRectZero
lblQRCodeResult.text = "QR Code wans't found"
return
}
let objMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if objMetadataMachineReadableCodeObject.type == AVMetadataObjectTypeQRCode {
let objBarCode = objCaptureVideoPreviewLayer?.transformedMetadataObjectForMetadataObject(objMetadataMachineReadableCodeObject as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
vwQRCode?.frame = objBarCode.bounds;
if objMetadataMachineReadableCodeObject.stringValue != nil {
lblQRCodeResult.text = objMetadataMachineReadableCodeObject.stringValue
}
}
}
}
Đây là mã đơn giản:
func scanbarcode()
{
view.backgroundColor = UIColor.blackColor()
captureSession = AVCaptureSession()
let videoCaptureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
failed();
return;
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypePDF417Code]
} else {
failed()
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
previewLayer.frame = view.layer.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
view.layer.addSublayer(previewLayer);
view.addSubview(closeBtn)
view.addSubview(backimg)
captureSession.startRunning();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func failed() {
let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
captureSession = nil
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if (captureSession?.running == false) {
captureSession.startRunning();
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if (captureSession?.running == true) {
captureSession.stopRunning();
}
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
foundCode(readableObject.stringValue);
}
// dismissViewControllerAnimated(true, completion: nil)
}
func foundCode(code: String) {
var createAccountErrorAlert: UIAlertView = UIAlertView()
createAccountErrorAlert.delegate = self
createAccountErrorAlert.title = "Alert"
createAccountErrorAlert.message = code
createAccountErrorAlert.addButtonWithTitle("ok")
createAccountErrorAlert.addButtonWithTitle("Retry")
createAccountErrorAlert.show()
NSUserDefaults.standardUserDefaults().setObject(code, forKey: "barcode")
NSUserDefaults.standardUserDefaults().synchronize()
ItemBarcode = code
print(code)
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Portrait
}
Nếu bạn đang phát triển cho iOS> 10.2 với Swift 4 thì bạn có thể thử giải pháp của tôi. Tôi lẫn lộn này và này hướng dẫn và đã đưa ra một ViewController mà quét một mã QR và print()
nó ra. Tôi cũng có một Công tắc trong giao diện người dùng của mình để bật đèn camera, cũng có thể hữu ích. Hiện tại tôi chỉ thử nghiệm nó trên iPhone SE, vui lòng cho tôi biết nếu nó không hoạt động trên iPhone mới hơn.
Ở đây bạn đi:
import UIKit
import AVFoundation
class QRCodeScanner: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
let captureSession: AVCaptureSession = AVCaptureSession()
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
let qrCodeFrameView: UIView = UIView()
var captureDevice: AVCaptureDevice?
override func viewDidLoad() {
// Get the back-facing camera for capturing videos
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera, .builtInDualCamera], mediaType: AVMediaType.video, position: .back)
captureDevice = deviceDiscoverySession.devices.first
if captureDevice == nil {
print("Failed to get the camera device")
return
}
do {
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
let input = try AVCaptureDeviceInput(device: captureDevice!)
// Set the input device on the capture session.
captureSession.addInput(input)
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
let captureMetadataOutput = AVCaptureMetadataOutput()
captureSession.addOutput(captureMetadataOutput)
// Set delegate and use the default dispatch queue to execute the call back
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
if let videoPreviewLayer = videoPreviewLayer {
videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoPreviewLayer.frame = view.layer.bounds
view.layer.addSublayer(videoPreviewLayer)
// Start video capture.
captureSession.startRunning()
if let hasFlash = captureDevice?.hasFlash, let hasTorch = captureDevice?.hasTorch {
if hasFlash && hasTorch {
view.bringSubview(toFront: bottomBar)
try captureDevice?.lockForConfiguration()
}
}
}
// QR Code Overlay
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubview(toFront: qrCodeFrameView)
} catch {
// If any error occurs, simply print it out and don't continue any more.
print("Error: \(error)")
return
}
}
// MARK: Buttons and Switch
@IBAction func switchFlashChanged(_ sender: UISwitch) {
do {
if sender.isOn {
captureDevice?.torchMode = .on
} else {
captureDevice?.torchMode = .off
}
}
}
// MARK: AVCaptureMetadataOutputObjectsDelegate
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
// Check if the metadataObjects array is not nil and it contains at least one object.
if metadataObjects.count == 0 {
qrCodeFrameView.frame = CGRect.zero
return
}
// Get the metadata object.
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if metadataObj.type == AVMetadataObject.ObjectType.qr {
// If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView.frame = barCodeObject!.bounds
print("QR Code: \(metadataObj.stringValue)")
}
}
}
Đôi khi nó cũng có thể hữu ích để tạo mã QR . Có một thư viện C tuyệt vời cho việc này hoạt động như một bùa mê. Nó được gọi là libqrencode . Viết một chế độ xem tùy chỉnh để hiển thị mã QR sau đó không khó và có thể được thực hiện với sự hiểu biết cơ bản về QuartzCore.
bạn có thể kiểm tra ZBarSDK để đọc Mã QR và mã ECN / ISBN thật đơn giản để tích hợp thử mã sau đây.
- (void)scanBarcodeWithZBarScanner
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
//Get the return value from controller
[reader setReturnBlock:^(BOOL value) {
}
và trong didFinishPickingMediaWithInfo, chúng tôi nhận được giá trị mã vạch.
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
barcodeValue = symbol.data;
// EXAMPLE: do something useful with the barcode image
barcodeImage = [info objectForKey:UIImagePickerControllerOriginalImage];
[_barcodeIV setImage:barcodeImage];
//set the values for to TextFields
[self setBarcodeValue:YES];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissViewControllerAnimated:YES completion:nil];
}