Puoi utilizzare ML Kit per riconoscere e decodificare i codici a barre.
Prima di iniziare
- Se non hai già aggiunto Firebase alla tua app, fallo seguendo i passaggi nella Guida introduttiva .
- Includi le librerie ML Kit nel tuo Podfile:
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
Dopo aver installato o aggiornato i Pod del tuo progetto, assicurati di aprire il tuo progetto Xcode usando il suo.xcworkspace
. - Nella tua app, importa Firebase:
Veloce
import Firebase
Obiettivo-C
@import Firebase;
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 dati pixel sufficienti.
I requisiti specifici per i dati dei pixel dipendono sia dal tipo di codice a barre che dalla quantità di dati in esso codificati (poiché la maggior parte dei codici a barre supporta un carico utile di lunghezza variabile). In generale, la più piccola unità significativa del codice a barre dovrebbe essere larga almeno 2 pixel (e per i codici bidimensionali, alta 2 pixel).
Ad esempio, i codici a barre EAN-13 sono costituiti da barre e spazi larghi 1, 2, 3 o 4 unità, quindi un'immagine di codici a barre EAN-13 idealmente ha barre e spazi di almeno 2, 4, 6 e 8 pixel di larghezza. Poiché un codice a barre EAN-13 è largo 95 unità in totale, il codice a barre deve essere largo almeno 190 pixel.
I formati più densi, come PDF417, richiedono dimensioni in pixel maggiori affinché ML Kit li legga in modo affidabile. Ad esempio, un codice PDF417 può contenere fino a 34 "parole" larghe 17 unità in una singola riga, che idealmente dovrebbero essere larghe almeno 1156 pixel.
Una scarsa messa a fuoco dell'immagine può compromettere la precisione della scansione. Se non ottieni risultati accettabili, prova a chiedere all'utente di acquisire nuovamente l'immagine.
Per le applicazioni tipiche, si consiglia di fornire un'immagine a risoluzione più elevata (come 1280x720 o 1920x1080), che renda i codici a barre rilevabili da una distanza maggiore dalla fotocamera.
Tuttavia, nelle applicazioni in cui la latenza è fondamentale, è possibile migliorare le prestazioni acquisendo immagini a una risoluzione inferiore, ma richiedendo che il codice a barre costituisca la maggior parte dell'immagine di input. Vedi anche Suggerimenti per migliorare le prestazioni in tempo reale .
1. Configurare il rilevatore di codici a barre
Se sai quali formati di codici a barre prevedi di leggere, puoi migliorare la velocità del rilevatore di codici a barre configurandolo in modo che rilevi solo quei formati. Ad esempio, per rilevare solo codice azteco e codici QR, creare un oggetto VisionBarcodeDetectorOptions
come nell'esempio seguente:
Veloce
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Sono supportati i seguenti formati:
- Codice128
- Codice39
- Codice93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- QR Code
- PDF417
- azteco
- Data Matrix
Obiettivo-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
) - Aztec (
FIRVisionBarcodeFormatAztec
) - Matrice di dati (
FIRVisionBarcodeFormatDataMatrix
)
2. Avviare il rilevatore di codici a barre
Per eseguire la scansione di codici a barre in un'immagine, passare l'immagine comeUIImage
o CMSampleBufferRef
al VisionBarcodeDetector
di detect(in:)
di VisionBarcodeDetector:- Ottieni un'istanza di
VisionBarcodeDetector
:Veloce
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Obiettivo-C
FIRVision *vision = [FIRVision vision]; FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector]; // Or, to change the default settings: // FIRVisionBarcodeDetector *barcodeDetector = // [vision barcodeDetectorWithOptions:options];
Crea un oggetto
VisionImage
usando unUIImage
o unCMSampleBufferRef
.Per utilizzare
UIImage
:- Se necessario, ruota l'immagine in modo che la sua proprietà
imageOrientation
sia.up
. - Crea un oggetto
VisionImage
utilizzando l'UIImage
ruotato correttamente. Non specificare metadati di rotazione: è necessario utilizzare il valore predefinito,.topLeft
.Veloce
let image = VisionImage(image: uiImage)
Obiettivo-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Per utilizzare un
CMSampleBufferRef
:Creare un oggetto
VisionImageMetadata
che specifichi l'orientamento dei dati dell'immagine contenuti nel bufferCMSampleBufferRef
.Per ottenere l'orientamento dell'immagine:
Veloce
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 } }
Obiettivo-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:
Veloce
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Obiettivo-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 l'oggettoCMSampleBufferRef
e i metadati di rotazione:Veloce
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Obiettivo-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Se necessario, ruota l'immagine in modo che la sua proprietà
- Quindi, passa l'immagine al metodo
detect(in:)
:Veloce
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Obiettivo-C
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. Ottieni informazioni dai codici a barre
Se l'operazione di riconoscimento del codice a barre ha esito positivo, il rilevatore restituisce un array di oggettiVisionBarcode
. Ogni oggetto VisionBarcode
rappresenta un codice a barre che è stato rilevato nell'immagine. Per ogni codice a barre, puoi ottenere le sue coordinate di delimitazione nell'immagine di input, così come i dati grezzi codificati dal codice a barre. Inoltre, se il rilevatore di codici a barre è stato in grado di determinare il tipo di dati codificati dal codice a barre, è possibile ottenere un oggetto contenente dati analizzati.Per esempio:
Veloce
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 } }
Obiettivo-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 le prestazioni in tempo reale
Se desideri eseguire la scansione di codici a barre in un'applicazione in tempo reale, segui queste linee guida per ottenere i framerate migliori:
Non acquisire input alla risoluzione nativa della fotocamera. Su alcuni dispositivi, l'acquisizione dell'input alla risoluzione nativa produce immagini estremamente grandi (10+ megapixel), il che si traduce in una latenza molto scarsa senza alcun vantaggio in termini di precisione. Invece, richiedi alla fotocamera solo la dimensione necessaria per il rilevamento del codice a barre: in genere non superiore a 2 megapixel.
Le preimpostazioni della sessione di acquisizione denominata (
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
e così via) non sono consigliate, tuttavia, poiché possono essere mappate a risoluzioni non adatte su alcuni dispositivi. Utilizzare invece le preimpostazioni specifiche comeAVCaptureSessionPreset1280x720
.Se la velocità di scansione è importante, è possibile ridurre ulteriormente la risoluzione di acquisizione dell'immagine. Tuttavia, tieni presente i requisiti di dimensione minima del codice a barre sopra descritti.
- Accelera le chiamate al rilevatore. Se un nuovo fotogramma video diventa disponibile mentre il rilevatore è in funzione, rilasciare il fotogramma.
- Se si utilizza l'output del rilevatore per sovrapporre la grafica all'immagine di input, ottenere prima il risultato da ML Kit, quindi eseguire il rendering dell'immagine e sovrapporre in un unico passaggio. In questo modo, si esegue il rendering sulla superficie di visualizzazione solo una volta per ciascun frame di input. Per un esempio, vedere le classi previewOverlayView e FIRDetectionOverlayView nell'app di esempio della vetrina.