Puoi utilizzare ML Kit per riconoscere e decodificare i codici a barre.
Prova
- Prova l'app di esempio per per vedere un esempio di utilizzo di questa API.
Prima di iniziare
- Includi i seguenti pod ML Kit nel podfile:
pod 'GoogleMLKit/BarcodeScanning', '15.5.0'
- Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando la relativa
.xcworkspace
. ML Kit è supportato in Xcode versione 12.4 o successiva.
Linee guida per l'immagine di input
-
Affinché ML Kit possa leggere accuratamente i codici a barre, le immagini di input devono contenere codici a barre rappresentati da un numero sufficiente di dati di pixel.
I requisiti specifici dei dati relativi ai pixel dipendono da entrambi i tipi di il codice a barre e la quantità di dati codificati al suo interno, dato che molti codici a barre per supportare un payload di dimensione variabile. In generale, la variante più piccola dell'unità di misura del codice a barre deve essere larga almeno 2 pixel e, per Codici bidimensionali, altezza di 2 pixel.
Ad esempio, i codici a barre EAN-13 sono composti da barre e spazi che sono 1, 2, 3 o 4 unità di larghezza, quindi un'immagine con codice a barre EAN-13 idealmente contiene barre e spazi di almeno 2, 4, 6 e 8 pixel di larghezza. Poiché un EAN-13 il codice a barre è largo in totale 95 unità, il codice a barre deve essere almeno 190 pixel di larghezza.
I formati più densi, come PDF417, richiedono dimensioni in pixel maggiori per ML Kit per leggerli in modo affidabile. Ad esempio, un codice PDF417 può avere fino a 34 "parole" di 17 unità di un'unica riga, il che sarebbe idealmente Larghezza 1156 pixel.
-
Una scarsa messa a fuoco dell'immagine può influire sulla precisione della scansione. Se la tua app non riceve accettabili, chiedi all'utente di recuperare l'immagine.
-
Per le applicazioni tipiche, consigliamo di fornire una maggiore un'immagine con risoluzione massima, ad esempio 1280 x 720 o 1920 x 1080, che consente di creare codici a barre scansionabili da una distanza maggiore dalla fotocamera.
Tuttavia, nelle applicazioni in cui la latenza è fondamentale, puoi migliorare rendimento delle immagini acquisendo immagini a una risoluzione più bassa, ma richiedendo il codice a barre costituisce la maggior parte dell'immagine di input. Vedi anche Suggerimenti per migliorare il rendimento in tempo reale.
1. Configura il lettore di codici a barre
Se sai quali formati di codici a barre ti aspetti di leggere, puoi migliorare la velocità del lettore di codici a barre configurandolo per scansionare solo quei formati.Ad esempio, per scansionare solo il codice Azteca e i codici QR, crea un
BarcodeScannerOptions
come nell'oggetto
nell'esempio seguente:
Swift
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
Sono supportati i seguenti formati:
- code128
- code39
- code93
- codaBar
- dataMatrix
- EAN13
- EAN8
- ITF
- qrCode
- UPCA
- UPCE
- PDF417
- Aztec
Objective-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
Sono supportati i seguenti formati:
- Codice-128 (
MLKBarcodeFormatCode128
) - Codice-39 (
MLKBarcodeFormatCode39
) - Codice-93 (
MLKBarcodeFormatCode93
) - Codabar (
MLKBarcodeFormatCodaBar
) - Matrice di dati (
MLKBarcodeFormatDataMatrix
) - EAN-13 (
MLKBarcodeFormatEAN13
) - EAN-8 (
MLKBarcodeFormatEAN8
) - ITF (
MLKBarcodeFormatITF
) - Codice QR (
MLKBarcodeFormatQRCode
) - UPC-A (
MLKBarcodeFormatUPCA
) - UPC-E (
MLKBarcodeFormatUPCE
) - PDF-417 (
MLKBarcodeFormatPDF417
) - Codice azteco (
MLKBarcodeFormatAztec
)
2. Prepara l'immagine di input
Per scansionare i codici a barre in un'immagine, passa l'immagine comeUIImage
o
CMSampleBufferRef
ai BarcodeScanner
di process()
o results(in:)
:
Crea un oggetto VisionImage
utilizzando un UIImage
o un
CMSampleBuffer
.
Se usi un UIImage
, segui questi passaggi:
- Crea un oggetto
VisionImage
conUIImage
. Assicurati di specificare il valore.orientation
corretto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se usi un CMSampleBuffer
, segui questi passaggi:
-
Specifica l'orientamento dei dati dell'immagine contenuti nei
CMSampleBuffer
.Per ottenere l'orientamento dell'immagine:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- Crea un oggetto
VisionImage
utilizzando il metodoCMSampleBuffer
oggetto e orientamento:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Recupera un'istanza del lettore di codici a barre
Recupera un'istanza diBarcodeScanner
:
Swift
let barcodeScanner = BarcodeScanner.barcodeScanner() // Or, to change the default settings: // let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
Objective-C
MLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner]; // Or, to change the default settings: // MLKBarcodeScanner *barcodeScanner = // [MLKBarcodeScanner barcodeScannerWithOptions:options];
4. Elabora l'immagine
Quindi, passa l'immagine al metodoprocess()
:
Swift
barcodeScanner.process(visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // Error handling return } // Recognized barcodes }
Objective-C
[barcodeScanner processImage:image completion:^(NSArray<MLKBarcode *> *_Nullable barcodes, NSError *_Nullable error) { if (error != nil) { // Error handling return; } if (barcodes.count > 0) { // Recognized barcodes } }];
5. Ricevere informazioni da codici a barre
Se la scansione del codice a barre ha esito positivo, lo scanner restituisce un array diBarcode
oggetti. Ogni oggetto Barcode
rappresenta un
del codice a barre rilevato nell'immagine. Per ogni codice a barre, puoi ottenere il suo
le coordinate di delimitazione nell'immagine di input, nonché i dati non elaborati codificati
codice a barre. Inoltre, se il lettore di codici a barre è riuscito a determinare il tipo di dati,
codificato dal codice a barre, puoi ottenere un oggetto contenente i dati analizzati.
Ad esempio:
Swift
for barcode in barcodes { let corners = barcode.cornerPoints let displayValue = barcode.displayValue let rawValue = barcode.rawValue let valueType = barcode.valueType switch valueType { case .wiFi: let ssid = barcode.wifi?.ssid let password = barcode.wifi?.password let encryptionType = barcode.wifi?.type case .URL: let title = barcode.url!.title let url = barcode.url!.url default: // See API reference for all supported value types } }
Objective-C
for (MLKBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; MLKBarcodeValueType valueType = barcode.valueType; switch (valueType) { case MLKBarcodeValueTypeWiFi: ssid = barcode.wifi.ssid; password = barcode.wifi.password; encryptionType = barcode.wifi.type; break; case MLKBarcodeValueTypeURL: url = barcode.URL.url; title = barcode.URL.title; break; // ... default: break; } }
Suggerimenti per migliorare il rendimento in tempo reale
Se desideri eseguire la scansione dei codici a barre in un'applicazione in tempo reale, procedi nel seguente modo: linee guida per ottenere le migliori frequenze fotogrammi:
-
Non acquisire input alla risoluzione nativa della videocamera. Su alcuni dispositivi, l'input alla risoluzione nativa produce risultati estremamente grandi (10+ megapixel), il che genera una latenza molto scarsa senza alcun vantaggio la precisione. Richiedi invece alla fotocamera solo la dimensione necessaria per la scansione dei codici a barre, che di solito non supera i 2 megapixel.
Le preimpostazioni della sessione di acquisizione denominate:
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
e così via), tuttavia, non sono consigliati in quanto possono essere mappati risoluzioni non adatte su alcuni dispositivi. Usa invece i predefiniti specifici ad esempioAVCaptureSessionPreset1280x720
.Se la velocità di scansione è importante, puoi ridurre ulteriormente l'acquisizione delle immagini risoluzione del problema. Tuttavia, tieni presente i requisiti minimi per le dimensioni del codice a barre. descritti sopra.
Se stai cercando di riconoscere i codici a barre da una sequenza di flussi di dati fotogrammi video, il riconoscimento potrebbe produrre risultati diversi da frame a frame. Devi attendere di ricevere una serie consecutiva dello stesso per avere la certezza di restituire un buon risultato.
La cifra di checksum non è supportata per ITF e CODE-39.
- Per elaborare i fotogrammi video, utilizza l'API sincrona
results(in:)
del rilevatore. Chiama questo metodo dal diAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
per ottenere in modo sincrono i risultati dal video specificato frame. Mantieni diAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
cometrue
per limitare le chiamate al rilevatore. Se un nuovo il fotogramma video diventa disponibile mentre il rilevatore è in esecuzione, quindi verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre elementi grafici l'immagine di input, occorre prima ottenere il risultato da ML Kit, quindi eseguire il rendering dell'immagine e la sovrapposizione in un solo passaggio. In questo modo, puoi visualizzare i contenuti solo una volta per ogni frame di input elaborato. Vedi la pagina updatePreviewOverlayViewWithLastFrame. nell'esempio della guida rapida di ML Kit.