Как я могу сканировать штрих-коды на iOS?
Как я могу просто сканировать штрих-коды на iPhone и/или iPad?
11 ответов:
мы создали приложение "штрих-коды" для iPhone. Он может декодировать QR-коды. Исходный код доступен из проект zxing в частности, вы хотите взглянуть на клиент для iPhone и частичный порт C++ основной библиотеки. Порт немного стар, начиная примерно с версии 0.9 кода Java, но все равно должен работать достаточно хорошо.
Если вам нужно сканировать другие форматы, например форматы 1D, вы можете продолжить порт кода Java в рамках этого проекта на C++.
редактировать: штрих-коды и
iphone
код в проекте был удален примерно в начале 2014 года.
проверить ZBar читает QR-код и коды ECN / ISBN и доступен как под лицензией LGPL v2.
как с выходом
iOS7
вам больше не нужно использовать внешний фреймворк или библиотеку. экосистема iOS с AVFoundation теперь полностью поддерживает сканирование почти каждый код от QR через EAN до UPC.просто взгляните на Tech Note и руководство по программированию AVFoundation.
AVMetadataObjectTypeQRCode
- твой друг.вот хороший учебник, который показывает, шаг за шагом: библиотека сканирования QR-кода iPhone iOS7
просто небольшой пример о том, как настроить его:
#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]; }
камера iPhone 4 больше чем capabale делать штрихкоды. Библиотека штрих-кодов Zebra crossing имеет вилку на github zxing-iphone. Это с открытым исходным кодом.
liteqr является "Lite QR Reader в Objective C портирован из zxing" на github и имеет поддержку Xcode 4.
есть две основные библиотеки:
ZXing библиотека, написанная на Java, а затем портированная на Objective C / C++ (только QR-код). И другой порт для ObjC был сделан, по TheLevelUp:ZXingObjC
ZBar программное обеспечение с открытым исходным кодом для чтения штрих-кодов на основе C.
по моим экспериментам, ZBar гораздо точнее и быстрее чем ZXing, по крайней мере на iPhone.
HOWTO: добавьте считыватель штрих-кода в приложение для iPhone, который указывает на ZBar iPhone в СДК, выглядит полезным (из другого потока).
Не уверен, что это поможет, но вот ссылка на открытый исходный код библиотека QR-кода. Как вы можете видеть, несколько человек уже использовали это для создания приложений для iphone.
в Википедии есть статьи объяснением какие QR-коды. На мой взгляд, QR-коды гораздо больше подходят для целей, чем стандартный штрих-код, когда речь идет о iphone, поскольку он был разработан для этого типа реализации.
Если поддержка iPad 2 или iPod Touch важна для вашего приложения, я бы выбрал сканер штрих-кода SDK, который может декодировать штрих-коды в размытых изображениях, таких как наш Scandit barcode scanner SDK для iOS и Android. Декодирование размытых изображений штрих-кода также полезно на телефонах с камерами с автофокусом, потому что пользователю не нужно ждать, пока автофокус сработает.
Scandit поставляется с бесплатным тарифным планом сообщества, а также имеет API продукта, что делает его легким для преобразования номеров штрих-кодов в названия продуктов.
(отказ от ответственности: я соучредитель Scandit)
вы могли бы взглянуть на исходный код iPhone DataMatrix Reader Стефана Хафенегера (Google Code project;архивный пост в блоге) если он все еще доступен.
вы можете найти другое родное решение iOS с помощью Swift 4 и Xcode 9 ниже. Уроженца
AVFoundation
рамки, используемые в этом решении.первая часть является подклассом
UIViewController
которые имеют соответствующие функции настройки и обработчика дляAVCaptureSession
.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) } }
вторая часть является продолжением нашего
UIViewController
подкласс дляAVCaptureMetadataOutputObjectsDelegate
где мы ловим трофейных результатов.extension BarCodeScannerViewController: AVCaptureMetadataOutputObjectsDelegate { func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { handleCapturedOutput(metadataObjects: metadataObjects) } }
обновление для Swift 4.2
.UIApplicationWillEnterForeground
измененияUIApplication.willEnterForegroundNotification
.