iPhone 및 / 또는 iPad에서 바코드를 간단히 스캔하려면 어떻게해야합니까?
iPhone 및 / 또는 iPad에서 바코드를 간단히 스캔하려면 어떻게해야합니까?
답변:
iPhone 용 '바코드'응용 프로그램을 제작했습니다. QR 코드를 해독 할 수 있습니다. 소스 코드는 zxing 프로젝트 에서 사용 가능합니다 . 특히, iPhone 클라이언트 와 핵심 라이브러리 의 부분 C ++ 포트를 살펴보고 싶습니다 . 포트는 Java 코드의 0.9 릴리스부터 약간 오래되었지만 여전히 잘 작동합니다.
1D 형식과 같은 다른 형식을 스캔해야하는 경우이 프로젝트 내의 Java 코드 포트를 C ++로 계속 사용할 수 있습니다.
편집 : iphone
프로젝트 의 바코드와 코드는 2014 년 초에 폐기되었습니다.
확인 ZBar는 QR 코드 및 ECN / ISBN 코드를 읽고 LGPL v2로 라이선스로 사용할 수 있습니다.
릴리스와 마찬가지로 iOS7
더 이상 외부 프레임 워크 또는 라이브러리를 사용할 필요가 없습니다. AVFoundation이 포함 된 iOS 에코 시스템은 이제 QR over EAN에서 UPC까지 거의 모든 코드 스캔을 완벽하게 지원합니다 .
기술 노트 와 AVFoundation 프로그래밍 안내서를 살펴보십시오 . AVMetadataObjectTypeQRCode
당신의 친구입니다.
다음은 단계별로 보여주는 멋진 자습서 입니다 .iPhone QR code scan library 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];
}
startRunning
누군가를 돕는 경우를 대비하여 위의 코드가 작동하도록 세션 을 호출해야한다는 것을 알았습니다 :)
iPhone 4 카메라는 바코드를 작성하는 것 이상의 역할을합니다. zebra crossing 바코드 라이브러리에는 github zxing-iphone 에 포크가 있습니다. 오픈 소스입니다.
두 가지 주요 라이브러리가 있습니다.
Java로 작성된 라이브러리를 ZXing 한 후 Objective C / C ++로 포트합니다 (QR 코드 만 해당). 그리고 TheLevelUp : ZXingObjC에 의해 ObjC에 대한 다른 포트가 수행되었습니다.
ZBar 는 C 기반 바코드를 읽기위한 오픈 소스 소프트웨어입니다.
내 실험에 따르면 ZBar는 적어도 iPhone에서 ZXing보다 훨씬 정확하고 빠릅니다 .
하우투 : ZBar iPhone SDK 를 가리키는 바코드 리더를 iPhone 앱에 추가하면 다른 스레드에서 유용하게 보입니다 .
아래에서 Swift 4 및 Xcode 9 를 사용하여 다른 기본 iOS 솔루션을 찾을 수 있습니다 . 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
.
metadataObjects
하고 handleCapturedOutput 함수 내부를 읽으십시오 .
이것이 도움이 될지 확실하지 않지만 여기에 오픈 소스 QR 코드 라이브러리에 대한 링크가 있습니다 . 보시다시피, 두 사람이 이미 이것을 사용하여 iPhone 용 앱을 만들었습니다.
Wikipedia에는 QR 코드가 무엇인지 설명하는 기사 가 있습니다. 제 생각에 QR 코드는 아이폰이 이런 유형의 구현을 위해 설계된 표준 바코드보다 목적에 훨씬 더 적합합니다.
응용 프로그램에 iPad 2 또는 iPod Touch 지원이 중요한 경우 iOS 및 Android 용 Scandit 바코드 스캐너 SDK 와 같이 흐릿한 이미지의 바코드를 해독 할 수있는 바코드 스캐너 SDK를 선택합니다 . 흐릿한 바코드 이미지 디코딩은 사용자가 자동 초점이 시작될 때까지 기다릴 필요가 없기 때문에 자동 초점 카메라가있는 전화기에서도 유용합니다.
Scandit에는 무료 커뮤니티 가격 계획이 제공되며 바코드 번호를 제품 이름으로 쉽게 변환 할 수있는 제품 API도 있습니다.
(면책 조항 : 저는 Scandit의 공동 설립자입니다)
사용 가능한 경우 Stefan Hafeneger의 iPhone DataMatrix Reader 소스 코드 ( Google 코드 프로젝트 ; 보관 된 블로그 게시물 )를 살펴볼 수 있습니다.
iPhone 카메라의 문제점은 (사용중인 톤이 많은) 첫 번째 모델에는 2 피트 미만의 거리에서 초점을 맞출 수없는 고정 초점 카메라가 있다는 것입니다. 이미지가 흐릿하고 왜곡되어 더 먼 거리에서 촬영하면 바코드의 세부 정보 / 정보가 충분하지 않습니다.
일부 회사는 고급 디 블러 링 기술을 사용하여이를 수용 할 수있는 iPhone 앱을 개발했습니다. Apple 앱 스토어에서 찾을 수있는 응용 프로그램은 pic2shop, RedLaser 및 ShopSavvy입니다. 모든 회사는 SDK를 사용할 수 있다고 발표했습니다. 일부는 무료 또는 매우 우선적 인 용어로 확인하십시오.
와 스위프트 5 그것은 빠르고 간단하고 슈퍼입니다!
코코아 포드 "BarcodeScanner"를 추가하면됩니다. 여기에 전체 코드가 있습니다.
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'Simple BarcodeScanner'
do
pod 'BarcodeScanner'
end
.plist 파일에 카메라 추가 권한이 있는지 확인하십시오
<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>
그리고 이런 방식으로 스캐너를 추가하고 ViewController에서 결과를 처리하십시오.
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)
}
}
여전히 궁금한 점이 있으시면 여기에서 전체 소스 코드로 샘플 애플리케이션을 확인하십시오.
기본 iOS 7 바코드 스캐너의 경우 GitHub에서 내 프로젝트를 살펴보십시오.
AVFramework를 사용 하여이 작업을 수행 할 수 있다고 생각합니다.이 작업을 수행하는 샘플 코드는 다음과 같습니다.
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
}
}
}
}
간단한 코드는 다음과 같습니다.
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
}
Swift 4로 iOS> 10.2를 개발하는 경우 내 솔루션을 사용해 볼 수 있습니다. 나는 혼합 이 와 이 자습서를하고 QR 코드와 스캔의 ViewController 함께했다 print()
그것을. UI에 스위치를 사용하여 카메라 조명을 토글하는 것도 도움이 될 수 있습니다. 지금은 iPhone SE에서만 테스트했지만 최신 iPhone에서 작동하지 않는 경우 알려주십시오.
여기 있습니다 :
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)")
}
}
}
때때로 QR 코드 를 생성 하는 것도 유용 할 수 있습니다 . 매력처럼 작동하는 멋진 C 라이브러리가 있습니다. 이것을 libqrencode 라고 합니다 . QR 코드를 표시하기위한 사용자 정의보기를 작성하는 것은 그리 어렵지 않으며 QuartzCore에 대한 기본 이해를 통해 수행 할 수 있습니다.
QR 코드와 ECN / ISBN 코드를 읽기 위해 ZBarSDK를 확인할 수 있습니다. 다음 코드를 통합하면 간단합니다.
- (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) {
}
didFinishPickingMediaWithInfo에서 우리는 바코드 값을 얻습니다.
- (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];
}