Bagaimana saya bisa memindai barcode di iOS?

189

Bagaimana saya bisa memindai barcode pada iPhone dan / atau iPad?

Stefan
sumber
7
Sayangnya, kamera iPhone saat ini mengerikan untuk membaca barcode karena lensanya tetap fokus ke ∞. Semoga berhasil!
Alastair Stuart
1
Baru saja menyelesaikan masalah ini maka akan menulis pengamatan saya. Saya menguji beberapa opsi. RSBarcodes_Swift - mudah diintegrasikan, tetapi memiliki kinerja yang sangat buruk. ZBarSDK - juga mudah diimplementasikan, juga mengambil beberapa pencarian google untuk menemukan caranya. Tetapi memiliki kinerja yang sangat baik (tidak memindai datamatrix dan kode langka lainnya) berfungsi sangat baik untuk barcode / QRCode. Tapi Skandal adalah yang terbaik dari mereka semua. Sangat cepat, memindai segalanya. sayangnya harganya cukup mahal.
Katafalkas

Jawaban:

82

Kami memproduksi aplikasi 'Barcode' untuk iPhone. Itu dapat mendekode Kode QR. Kode sumber tersedia dari proyek zxing ; khusus, Anda ingin melihat klien iPhone dan port C ++ parsial dari perpustakaan inti . Port ini sedikit tua, dari sekitar rilis 0,9 dari kode Java, tetapi harus tetap berfungsi dengan baik.

Jika Anda perlu memindai format lain, seperti format 1D, Anda bisa melanjutkan port kode Java dalam proyek ini ke C ++.

EDIT: Barcode dan iphonekode dalam proyek sudah dihentikan sekitar awal 2014.

Sean Owen
sumber
Melihat lisensi seperti apa yang digunakannya. Saya ingin membuat aplikasi berbayar yang menggunakan Zbar. Apakah itu mungkin berdasarkan perjanjian lisensi?
Radu
1
Untuk lebih jelasnya, pada saat ini, ZXing pada iPhone hanya mendukung QR Codes?
RefuX
Saya percaya lebih banyak porting ke C ++, tapi sayangnya portnya masih kasar dan ketinggalan jaman dari kode Java. Jadi, ya lebih banyak didukung meskipun mungkin tidak baik.
Sean Owen
ZXing untuk iPhone masih memiliki kebocoran memori sebesar 1,7 ver.
Yoon Lee
Saya mengerti dari daftar masalah pada git of zXing bahwa kita dapat memindai barcode hanya dalam mode landscape.
Sagrian
81

Lihat ZBar membaca QR Code dan ECN / ISBN code dan tersedia di bawah lisensi LGPL v2.

Vijay
sumber
5
Sebagian benar. ZBar.app dilisensikan di bawah Lisensi Apache (Versi 2.0), namun perpustakaan dilisensikan di bawah LGPL v2.
Sean
3
Sayangnya lisensi mengharuskan Anda untuk berbagi file objek aplikasi Anda dengan siapa pun yang memintanya .. lihat zbar.sourceforge.net/iphone/sdkdoc/licensing.html
Ben Clayton
1
@ BenClayton apa artinya berbagi file objek aplikasi?
Dejell
@Odelya Mengirim file .o yang dibuat oleh Xcode kepada siapa pun, secara teoritis memungkinkan mereka untuk membangun aplikasi Anda. Saya jelas tidak senang melakukan hal ini (terutama untuk klien saya) sehingga ZBar keluar dari pertanyaan untuk kami. Halaman lisensi ZBar menyarankan Anda seharusnya 'berharap tidak ada yang meminta mereka!'
Ben Clayton
@ BenClayton A. Terima kasih B. Saya bisa mengubah komponen jika ada yang bertanya dan meminta pengguna aplikasi yang sudah mengunduh, untuk mengunduh versi yang lebih baru. Cukup? C. Jadi perpustakaan mana yang Anda gunakan?
Dejell
56

Seperti rilis iOS7Anda tidak perlu lagi menggunakan kerangka kerja eksternal atau perpustakaan. Ekosistem iOS dengan AVFoundation sekarang sepenuhnya mendukung pemindaian hampir setiap kode dari QR over EAN ke UPC.

Lihat saja Catatan Tek dan panduan pemrograman AVFoundation. AVMetadataObjectTypeQRCodeadalah temanmu

Berikut ini adalah tutorial yang bagus yang menunjukkan langkah demi langkah: iPhone QR code scan library iOS7

Hanya sedikit contoh tentang cara mengaturnya:

#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];
}
Alexander
sumber
1
Jika Anda ingin mendeteksi barcode dari gambar di iOS8, tutorial ini mungkin bisa membantu.
NSDeveloper
Saya menemukan saya harus memanggil startRunningsesi untuk mendapatkan kode di atas untuk bekerja dalam kasus yang membantu siapa pun :)
Chris
13

Kamera iPhone 4 lebih dari sekadar kemampuan melakukan barcode. Perpustakaan barcode zebra crossing memiliki garpu pada github zxing-iphone . Ini open-source.

Aris Bartee
sumber
1
Kiriman Anda tampaknya menyiratkan bahwa port ZXing ini dapat memindai lebih dari sekadar QRCodes? Apakah itu masalahnya?
RefuX
4
Garpu github tampaknya sudah mati, seperti yang ditunjukkan oleh masalah ini: github.com/joelind/zxing-iphone/issues/3
Josh Brown
10

liteqr adalah "Lite QR Reader di Objective C porting dari zxing" di github dan memiliki dukungan untuk Xcode 4.

Josh Brown
sumber
10

Ada dua perpustakaan utama:

  • ZXing perpustakaan yang ditulis dalam Java dan kemudian porting ke Objective C / C ++ (hanya kode QR). Dan port lain ke ObjC telah dilakukan, oleh TheLevelUp: ZXingObjC

  • ZBar perangkat lunak sumber terbuka untuk membaca kode batang, berbasis C.

Menurut eksperimen saya, ZBar jauh lebih akurat dan cepat daripada ZXing, setidaknya di iPhone.

MonsieurDart
sumber
Menurut saya ZXingObjC adalah yang harus didorong ke atas dengan suara terbanyak sekarang. Saya belum menggunakannya belum , tapi deskripsi mengatakan itu pada paritas dengan ZXing 2.0.
Shaolo
Lisensi ZBar mengharuskan Anda untuk menawarkan file objek kepada pengguna, sehingga mereka dapat menjalankannya dan dapat memodifikasi perpustakaan mereka juga.
Dejell
Saya merekomendasikan ZXingObjC
Dejell
7

Anda dapat menemukan solusi iOS asli lainnya menggunakan Swift 4 dan Xcode 9 di bawah. AVFoundationKerangka kerja asli yang digunakan dalam solusi ini.

Bagian pertama adalah subclass UIViewControlleryang memiliki fungsi pengaturan dan penangan terkait 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)
    }

}

Bagian kedua adalah ekstensi dari UIViewControllersubclass kami untuk AVCaptureMetadataOutputObjectsDelegatetempat kami menangkap output yang ditangkap.

extension BarCodeScannerViewController: AVCaptureMetadataOutputObjectsDelegate {

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

}

Pembaruan untuk Swift 4.2

.UIApplicationWillEnterForegroundberubah sebagai UIApplication.willEnterForegroundNotification.

abdullahselek
sumber
apakah ini akan memberikan nama Produk, ukuran, harga, url produk, mata uang, nama penyimpanan? atau hanya akan memberikan nomor barcode @abdullahselek
R. Mohan
@ R.Mohan ini terkait dengan barcode yang Anda baca. Silakan periksa AVCaptureMetadataOutput dan AVMetadataMachineReadableCodeObject dan coba baca metadataObjectsdi dalam fungsi handleCapturedOutput .
abdullahselek
Ok, akan coba itu. Terima kasih atas balasannya @abdullahselek
R. Mohan
5

Tidak yakin apakah ini akan membantu tetapi di sini ada tautan ke perpustakaan QR Code sumber terbuka . Seperti yang Anda lihat, beberapa orang telah menggunakan ini untuk membuat aplikasi untuk iphone.

Wikipedia memiliki artikel yang menjelaskan apa itu QR Codes . Menurut pendapat saya, QR Code jauh lebih cocok untuk tujuan daripada barcode standar di mana iphone terkait karena dirancang untuk jenis implementasi ini.

lexx
sumber
5

Jika dukungan untuk iPad 2 atau iPod Touch penting untuk aplikasi Anda, saya akan memilih SDK pemindai barcode yang dapat men-decode barcode dalam gambar buram, seperti SDK pemindai barcode Skandit untuk iOS dan Android. Penguraian gambar barcode yang buram juga membantu pada ponsel dengan kamera autofocus karena pengguna tidak harus menunggu autofocus untuk masuk.

Scandit hadir dengan paket harga komunitas gratis dan juga memiliki API produk yang memudahkan untuk mengubah nomor barcode menjadi nama produk.

(Penafian: Saya adalah salah satu pendiri Scandit)

floerkem
sumber
4

Anda dapat melihat Kode Sumber Pembaca DataMatrix iPhone iPhone Stefan Hafeneger ( proyek Google Code ; posting blog yang diarsipkan ) jika masih tersedia.

Orang belanda
sumber
Bagaimana pengalaman Anda dengan aplikasi ini? Bagi saya perlu 10s atau lebih untuk memecahkan kode barcode datamatrix sederhana!
iamj4de
1
Tautan diubah ke stefan.hafeneger.name/blog/2009/09/08/...
Suresh Varma
1
Tautan langsung (saya pikir Google tidak akan
apakah ada yang tahu apa nama resmi aplikasi Stefan di appstore? Saya ingin mengunduhnya sebelum saya menyelami kode yang sebenarnya.
macutan
3

Masalah dengan kamera iPhone adalah bahwa model pertama (yang banyak digunakan) memiliki kamera dengan fokus tetap yang tidak dapat mengambil gambar dengan fokus untuk jarak di bawah 2 kaki. Gambar buram dan terdistorsi dan jika diambil dari jarak yang lebih jauh tidak ada cukup detail / informasi dari barcode.

Beberapa perusahaan telah mengembangkan aplikasi iPhone yang dapat mengakomodasi hal itu dengan menggunakan teknologi de-blurring yang canggih. Aplikasi tersebut dapat Anda temukan di Apple app store: pic2shop, RedLaser dan ShopSavvy. Semua perusahaan telah mengumumkan bahwa mereka juga memiliki SDK yang tersedia - beberapa gratis atau syarat yang sangat istimewa, periksa yang keluar.

Nas Banov
sumber
Saya sudah mencoba menggunakan ShopSavvy dengan iphone 3G. Ini lucu, tetapi sering crash, dan memiliki waktu yang sangat, sangat sulit membaca barcode yang sangat jelas dan datar.
James Moore
1
Dan saya baru saja mencoba pic2shop. Kutipan dari tunangan saya: "ini seharusnya membuat hidup kita lebih mudah BAGAIMANA?" Ini aplikasi yang imut, tetapi sebenarnya tidak bisa membaca barcode sejauh yang saya tahu.
James Moore
Format mana yang Anda coba baca? Saya mencoba menggunakan pic2shop untuk memindai EAN dan berfungsi dengan sangat baik. Biaya lisensinya mahal, bahkan lebih dari RedLaser.
iamj4de
2

dengan Swift 5 itu Sederhana dan Super cepat !!

Anda hanya perlu menambahkan cocoa pod "BarcodeScanner" di sini adalah kode lengkap

source 'https://github.com/CocoaPods/Specs.git' 
platform :ios, '12.0' 
target 'Simple BarcodeScanner' 
do   
pod 'BarcodeScanner' 
end

Pastikan menambahkan izin Kamera di file .plist Anda

<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>

Dan tambahkan Pemindai dan tangani hasilnya di ViewController Anda dengan cara ini

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)
    }
}

Masih dan ada pertanyaan atau tantangan, silakan periksa contoh aplikasi di sini dengan kode sumber lengkap

swiftBoy
sumber
1

Saya percaya ini dapat dilakukan dengan menggunakan AVFramework, berikut adalah contoh kode untuk melakukan ini

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
            }
        }
    }
}
Jeff D
sumber
1

Ini kode sederhana:

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
}
shikha kochar
sumber
1

Jika Anda mengembangkan untuk iOS> 10.2 dengan Swift 4 maka Anda dapat mencoba solusi saya. Saya bercampur ini dan ini tutorial dan datang dengan ViewController yang memindai QR Code dan print()keluar. Saya juga memiliki Switch di UI saya untuk menyalakan lampu kamera, mungkin bisa membantu juga. Untuk saat ini saya hanya mengujinya pada iPhone SE, beri tahu saya jika itu tidak berfungsi pada iPhone yang lebih baru.

Ini dia:

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)")
        }
    }
}
Paul Spiesberger
sumber
0

Terkadang bermanfaat juga untuk menghasilkan kode QR . Ada perpustakaan C yang luar biasa untuk ini yang berfungsi seperti pesona. Ini disebut libqrencode . Menulis tampilan khusus untuk menampilkan kode QR tidaklah sulit dan dapat dilakukan dengan pemahaman dasar tentang QuartzCore.

GorillaPatch
sumber
apakah Anda tahu tutorial tentang cara memasukkan ini ke proyek iOS xCode?
james
maukah Anda berbagi bagaimana Anda menghasilkan tampilan menggunakan kuartcore? akan menjadi penghemat waktu yang besar: P
ThomasRS
Itu benar. Namun, pastikan Anda patuh dengan lisensi perangkat lunak, perpustakaan diterbitkan bersama.
GorillaPatch
Pertanyaan ini tentang pengakuan, bukan generasi.
MonsieurDart
0

Anda dapat memeriksa ZBarSDK untuk membaca kode QR dan kode ECN / ISBN. Sangat mudah untuk mengintegrasikan coba kode berikut.

- (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) {

}

dan di didFinishPickingMediaWithInfo kita mendapatkan nilai kode bar.

    - (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];
   }
Amit Shelgaonkar
sumber