Vous pouvez utiliser ML Kit pour reconnaître et décoder les codes à barres.
Avant de commencer
- Si vous n'avez pas encore ajouté Firebase à votre application, suivez la procédure décrite dans le guide de démarrage.
- Incluez les bibliothèques ML Kit dans votre Podfile :
pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel'
Après avoir installé ou mis à jour les pods de votre projet, veillez à ouvrir votre projet Xcode à l'aide de son.xcworkspace
. - Dans votre application, importez Firebase:
Swift
import Firebase
Objective-C
@import Firebase;
Consignes concernant les images d'entrée
-
Pour que ML Kit lise précisément les codes-barres, les images d'entrée doivent contenir des codes-barres représentés par suffisamment de données de pixel.
Les exigences spécifiques concernant les données de pixel dépendent à la fois du type de code-barres et de la quantité de données qui y sont encodées (puisque la plupart des codes-barres acceptent une charge utile de longueur variable). En général, la plus petite unité significative du code-barres doit avoir une largeur d'au moins deux pixels (et une hauteur de deux pixels pour les codes 2D).
Par exemple, les codes-barres EAN-13 sont composés de barres et d'espaces de 1, 2, 3 ou 4 unités de largeur. Une image de code-barres EAN-13 doit donc idéalement comporter des barres et des espaces d'au moins 2, 4, 6 et 8 pixels de largeur. Étant donné qu'un code-barres EAN-13 mesure 95 unités de large au total, il doit avoir une largeur d'au moins 190 pixels.
Les formats plus denses, tels que PDF417, nécessitent des dimensions de pixel plus élevées pour que ML Kit puisse les lire de manière fiable. Par exemple, un code PDF417 peut comporter jusqu'à 34 "mots" de 17 unités de large sur une seule ligne, qui doit idéalement avoir une largeur d'au moins 1 156 pixels.
-
Un mauvais cadrage de l'image peut nuire à la précision de la numérisation. Si vous n'obtenez pas de résultats acceptables, essayez de demander à l'utilisateur de reprendre la photo.
-
Pour les applications standards, nous vous recommandons de fournir une image de résolution plus élevée (par exemple, 1 280 x 720 ou 1 920 x 1 080), ce qui permet de détecter les codes-barres à une plus grande distance de l'appareil photo.
Toutefois, dans les applications où la latence est critique, vous pouvez améliorer les performances en capturant des images à une résolution inférieure, mais en exigeant que le code-barres représente la majeure partie de l'image d'entrée. Consultez également les conseils pour améliorer les performances en temps réel.
1. Configurer le détecteur de codes-barres
Si vous savez quels formats de codes-barres vous prévoyez de lire, vous pouvez améliorer la vitesse du détecteur de codes-barres en le configurant pour qu'il ne détecte que ces formats.Par exemple, pour ne détecter que les codes Aztec et les codes QR, créez un objet VisionBarcodeDetectorOptions
comme dans l'exemple suivant:
Swift
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Les formats suivants sont acceptés :
- Code128
- Code39
- Code93
- CodaBar
- EAN13
- EAN8
- ITF
- UPCA
- UPCE
- Code QR
- PDF417
- Aztèque
- DataMatrix
Objective-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Les formats suivants sont acceptés :
- Code 128 (
FIRVisionBarcodeFormatCode128
) - Code 39 (
FIRVisionBarcodeFormatCode39
) - Code 93 (
FIRVisionBarcodeFormatCode93
) - Codabar (
FIRVisionBarcodeFormatCodaBar
) - EAN-13 (
FIRVisionBarcodeFormatEAN13
) - EAN-8 (
FIRVisionBarcodeFormatEAN8
) - ITF (
FIRVisionBarcodeFormatITF
) - UPC-A (
FIRVisionBarcodeFormatUPCA
) - UPC-E (
FIRVisionBarcodeFormatUPCE
) - Code QR (
FIRVisionBarcodeFormatQRCode
) - PDF417 (
FIRVisionBarcodeFormatPDF417
) - Aztèque (
FIRVisionBarcodeFormatAztec
) - Matrice de données (
FIRVisionBarcodeFormatDataMatrix
)
2. Exécuter le détecteur de codes-barres
Pour scanner des codes-barres dans une image, transmettez l'image en tant queUIImage
ou CMSampleBufferRef
à la méthode detect(in:)
de VisionBarcodeDetector
:
- Obtenez une instance de
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];
-
Créez un objet
VisionImage
à l'aide d'unUIImage
ou d'unCMSampleBufferRef
.Pour utiliser une
UIImage
:- Si nécessaire, faites pivoter l'image pour que sa propriété
imageOrientation
soit.up
. - Créez un objet
VisionImage
à l'aide de l'UIImage
correctement orienté. Ne spécifiez aucune métadonnées de rotation. La valeur par défaut,.topLeft
, doit être utilisée.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Pour utiliser une
CMSampleBufferRef
:-
Créez un objet
VisionImageMetadata
qui spécifie l'orientation des données d'image contenues dans le tamponCMSampleBufferRef
.Pour obtenir l'orientation de l'image:
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; } }
Créez ensuite l'objet de métadonnées:
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];
- Créez un objet
VisionImage
à l'aide de l'objetCMSampleBufferRef
et des métadonnées de rotation:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Si nécessaire, faites pivoter l'image pour que sa propriété
-
Transmettez ensuite l'image à la méthode
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. Obtenir des informations à partir de codes-barres
Si l'opération de reconnaissance de code-barres aboutit, le détecteur renvoie un tableau d'objetsVisionBarcode
. Chaque objet VisionBarcode
représente un code-barres détecté dans l'image. Pour chaque code-barres, vous pouvez obtenir ses coordonnées de délimitation dans l'image d'entrée, ainsi que les données brutes encodées par le code-barres. De plus, si le détecteur de codes-barres a pu déterminer le type de données encodées par le code-barres, vous pouvez obtenir un objet contenant des données analysées.
Exemple :
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; } }
Conseils pour améliorer les performances en temps réel
Si vous souhaitez scanner des codes-barres dans une application en temps réel, suivez ces consignes pour obtenir les meilleurs fréquences d'images:
-
Ne capturez pas l'entrée à la résolution native de l'appareil photo. Sur certains appareils, la capture d'entrée à la résolution native produit des images extrêmement grandes (plus de 10 mégapixels), ce qui entraîne une latence très faible sans aucun avantage en termes de précision. Demandez plutôt la taille de la caméra requise pour la détection des codes-barres: généralement pas plus de 2 mégapixels.
Toutefois, les préréglages de session de capture nommés (
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
, etc.) ne sont pas recommandés, car ils peuvent être mappés à des résolutions inappropriées sur certains appareils. Utilisez plutôt des préréglages spécifiques tels queAVCaptureSessionPreset1280x720
.Si la vitesse de numérisation est importante, vous pouvez réduire davantage la résolution de capture d'image. Toutefois, n'oubliez pas les exigences minimales de taille de code-barres décrites ci-dessus.
- Limitez les appels au détecteur. Si un nouveau frame vidéo devient disponible pendant l'exécution du détecteur, supprimez-le.
- Si vous utilisez la sortie du détecteur pour superposer des éléments graphiques à l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis affichez l'image et superposez-la en une seule étape. Vous ne procédez ainsi qu'une seule fois pour chaque frame d'entrée. Pour en savoir plus, consultez les classes previewOverlayView et FIRDetectionOverlayView dans l'application exemple de démonstration.