Puoi utilizzare ML Kit per riconoscere e decodificare i codici a barre.
Prima di iniziare
- Se non hai già aggiunto Firebase alla tua app, puoi farlo seguendo le istruzioni riportate in passaggi nella Guida introduttiva.
- Includi le librerie del kit ML nel tuo podfile:
Dopo aver installato o aggiornato i pod del progetto, assicurati di aprire Xcode utilizzando il suopod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
.xcworkspace
. - Nell'app, importa Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
Linee guida per le immagini 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 la maggior parte dei codici a barre supporta un payload di lunghezza 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 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 messa a fuoco scadente dell'immagine può influire sulla precisione della scansione. Se non ottieni risultati accettabili, prova a chiedere all'utente di acquisire di nuovo l'immagine.
-
Per le applicazioni tipiche, si consiglia di fornire una maggiore un'immagine con risoluzione massima (ad esempio 1280 x 720 o 1920 x 1080), che crea i codici a barre rilevabile da una distanza maggiore dalla fotocamera.
Tuttavia, nelle applicazioni in cui la latenza è fondamentale, puoi migliorare le prestazioni acquisendo immagini a una risoluzione inferiore, ma richiedendo che il codice a barre rappresenti la maggior parte dell'immagine di input. Vedi anche Suggerimenti per migliorare il rendimento in tempo reale.
1. Configurare il rilevatore di codici a barre
Se sai quali formati di codici a barre ti aspetti di leggere, puoi migliorare la velocità del rilevatore di codici a barre configurandolo per rilevare solo quei formati.Ad esempio, per rilevare solo il codice Azteca e i codici QR, crea un
VisionBarcodeDetectorOptions
come nell'oggetto
nell'esempio seguente:
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Sono supportati i seguenti formati:
- Codice128
- Codice39
- Codice93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- Codice QR
- PDF417
- Azteco
- Matrice di dati
Objective-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Sono supportati i seguenti formati:
- Codice 128 (
FIRVisionBarcodeFormatCode128
) - Codice 39 (
FIRVisionBarcodeFormatCode39
) - Codice 93 (
FIRVisionBarcodeFormatCode93
) - Codabar (
FIRVisionBarcodeFormatCodaBar
) - EAN-13 (
FIRVisionBarcodeFormatEAN13
) - EAN-8 (
FIRVisionBarcodeFormatEAN8
) - ITF (
FIRVisionBarcodeFormatITF
) - UPC-A (
FIRVisionBarcodeFormatUPCA
) - UPC-E (
FIRVisionBarcodeFormatUPCE
) - Codice QR (
FIRVisionBarcodeFormatQRCode
) - PDF417 (
FIRVisionBarcodeFormatPDF417
) - Azteco (
FIRVisionBarcodeFormatAztec
) - Matrice di dati (
FIRVisionBarcodeFormatDataMatrix
)
2. Attiva il rilevatore di codici a barre
Per scansionare i codici a barre in un'immagine, passa l'immagine comeUIImage
o
CMSampleBufferRef
a detect(in:)
di VisionBarcodeDetector
:
- Recupera un'istanza di
VisionBarcodeDetector
:Swift
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Objective-C
FIRVision *vision = [FIRVision vision]; FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector]; // Or, to change the default settings: // FIRVisionBarcodeDetector *barcodeDetector = // [vision barcodeDetectorWithOptions:options];
-
Crea un oggetto
VisionImage
utilizzando unUIImage
o unCMSampleBufferRef
.Per usare un
UIImage
:- Se necessario, ruota l'immagine in modo che
imageOrientation
è.up
. - Crea un oggetto
VisionImage
utilizzando l'oggetto ruotato correttamenteUIImage
. Non specificare alcun metadato di rotazione (l'impostazione predefinita) è necessario utilizzare il valore.topLeft
.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Per usare un
CMSampleBufferRef
:-
Crea un oggetto
VisionImageMetadata
che specifichi l'orientamento dei dati dell'immagine contenuti bufferCMSampleBufferRef
.Per ottenere l'orientamento dell'immagine:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> VisionDetectorImageOrientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftTop : .rightTop case .landscapeLeft: return cameraPosition == .front ? .bottomLeft : .topLeft case .portraitUpsideDown: return cameraPosition == .front ? .rightBottom : .leftBottom case .landscapeRight: return cameraPosition == .front ? .topRight : .bottomRight case .faceDown, .faceUp, .unknown: return .leftTop } }
Objective-C
- (FIRVisionDetectorImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationLeftTop; } else { return FIRVisionDetectorImageOrientationRightTop; } case UIDeviceOrientationLandscapeLeft: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationBottomLeft; } else { return FIRVisionDetectorImageOrientationTopLeft; } case UIDeviceOrientationPortraitUpsideDown: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationRightBottom; } else { return FIRVisionDetectorImageOrientationLeftBottom; } case UIDeviceOrientationLandscapeRight: if (cameraPosition == AVCaptureDevicePositionFront) { return FIRVisionDetectorImageOrientationTopRight; } else { return FIRVisionDetectorImageOrientationBottomRight; } default: return FIRVisionDetectorImageOrientationTopLeft; } }
Quindi, crea l'oggetto metadati:
Swift
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objective-C
FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init]; AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionBack; // Set to the capture device you used. metadata.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
- Crea un oggetto
VisionImage
utilizzando il metodo OggettoCMSampleBufferRef
e metadati di rotazione:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Se necessario, ruota l'immagine in modo che
-
Quindi, passa l'immagine al metodo
detect(in:)
:Swift
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Objective-C
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. Ricevere informazioni da codici a barre
Se il riconoscimento del codice a barre ha esito positivo, il rilevatore restituisce un array diVisionBarcode
oggetti. Ogni oggetto VisionBarcode
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 rilevatore 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 (FIRVisionBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; FIRVisionBarcodeValueType valueType = barcode.valueType; switch (valueType) { case FIRVisionBarcodeValueTypeWiFi: // ssid = barcode.wifi.ssid; // password = barcode.wifi.password; // encryptionType = barcode.wifi.type; break; case FIRVisionBarcodeValueTypeURL: // 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 le dimensioni richieste per il rilevamento del codice a barre: in genere non più di 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.
- Limita le chiamate al rilevatore. Se un nuovo fotogramma disponibili mentre il rilevatore è in esecuzione, abbandona il frame.
- Se utilizzi l'output del rilevatore per sovrapporre la grafica all'immagine di input, ottieni prima il risultato da ML Kit, poi esegui il rendering dell'immagine e la sovrapposizione in un unico passaggio. In questo modo, esegui il rendering sulla superficie di visualizzazione solo una volta per ogni frame di input. Guarda previewOverlayView. e FIRDetectionOverlayView nell'app di esempio Showcase.