Comment puis-je scanner les codes à barres sur iOS?

Comment puis-je simplement numériser des codes à barres sur iPhone et/ou iPad?

181
demandé sur Deduplicator 0000-00-00 00:00:00

11 réponses

nous avons produit l'application "codes-barres" pour l'iPhone. Il peut décoder les codes QR. Le code source est disponible à partir du ZXing project ; plus précisément, vous voulez jeter un oeil au iPhone client et le partielle C++ port of the core library . Le port est un peu vieux, de circa la version 0.9 du code Java, mais devrait quand même fonctionner assez bien.

Si vous avez besoin de scanner d'autres formats, comme les formats 1D, vous pouvez continuer le port du code Java dans ce projet vers C++.

EDIT: les codes-barres et le code iphone dans le projet ont été retirés vers le début de 2014.

80
répondu Sean Owen 2015-03-19 03:46:23

Check out ZBar lit les codes QR et ECN/ISBN et est disponible sous licence LGPL v2.

81
répondu Vijay 2012-10-20 15:17:35

comme avec la version de iOS7 vous n'avez plus besoin d'utiliser un cadre externe ou une bibliothèque. l'écosystème iOS avec AVFoundation supporte maintenant pleinement le balayage de presque tous les codes de QR over EAN à UPC.

il suffit de jeter un oeil à la Note technique et le guide de programmation AVFoundation. AVMetadataObjectTypeQRCode est votre ami.

Voici une belle tutoriel , qui montre étape par étape: iPhone QR code scan library iOS7

juste un petit exemple sur la façon de le configurer:

#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];
}
50
répondu Alexander 2013-10-14 14:49:07

l'appareil photo iPhone 4 est plus que capabale de faire des codes à barres. La bibliothèque de codes à barres Zebra crossing dispose d'une fourchette sur github ZXing-iphone . Il est open-source.

13
répondu Aris Bartee 2011-09-06 14:01:08

liteqr est un "lecteur Lite QR dans L'objectif c porté de zxing" sur github et a le soutien pour Xcode 4.

10
répondu Josh Brown 2011-06-06 15:00:31

il y a deux grandes bibliothèques:

  • ZXing une bibliothèque écrite en Java et ensuite portée à L'Objectif C / C++ (code QR seulement). Et un autre port à ObjC a été fait, par TheLevelUp: ZXingObjC

  • ZBar est un logiciel open source pour la lecture de codes à barres, C en fonction.

Selon mes expériences, ZBar est beaucoup plus précis et rapide que ZXing, au moins sur iPhone.

10
répondu MonsieurDart 2012-11-19 09:11:24

pas sûr que cela aidera, mais voici un lien vers un code source ouvert bibliothèque de Code QR . Comme vous pouvez le voir un couple de personnes ont déjà utilisé cette fonction pour créer des applications pour l'iphone.

Wikipedia a un article expliquant quels sont les codes QR . À mon avis, les codes QR sont beaucoup plus adaptés à cet usage que le code à barres standard pour l'iphone car il a été conçu pour ce type de mise en œuvre.

5
répondu lexx 2009-05-08 08:17:46

si la prise en charge de l'iPad 2 ou de L'iPod Touch est importante pour votre application, je choisirais un SDK scanner de code à barres qui peut décoder les codes à barres dans des images floues, comme notre scanner de code à barres Scandit SDK pour iOS et Android. Le décodage d'images de codes à barres floues est également utile sur les téléphones avec caméras autofocus car l'utilisateur n'a pas à attendre que l'autofocus se déclenche.

Scandit est livré avec un plan de prix communautaire gratuit et a également un produit API qui facilite la conversion des codes à barres en noms de produits.

(Disclaimer: je suis un des co-fondateurs de Scandit)

5
répondu floerkem 2012-09-25 11:49:36

vous pouvez jeter un oeil à Stefan Hafeneger's iPhone DataMatrix Reader code Source ( Google Code project ; blog archivé ) si elle est encore disponible.

4
répondu Galwegian 2011-06-03 02:00:51

vous pouvez trouver une autre solution native iOS en utilisant Swift 4 et Xcode 9 ci-dessous. Cadre natif AVFoundation utilisé dans cette solution.

la première partie est la sous-classe A de UIViewController qui ont des fonctions de configuration et de gestion connexes pour 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)
    }

}

deuxième partie est l'extension de notre UIViewController sous-classe pour AVCaptureMetadataOutputObjectsDelegate où nous capturons sortie.

extension BarCodeScannerViewController: AVCaptureMetadataOutputObjectsDelegate {

    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        handleCapturedOutput(metadataObjects: metadataObjects)
    }

}

mise à jour pour Swift 4.2

.UIApplicationWillEnterForeground change as UIApplication.willEnterForegroundNotification .

4
répondu abdullahselek 2018-09-23 19:06:51