Vous pouvez utiliser ML Kit pour reconnaître et décoder les codes-barres.
Avant que tu commences
- Si vous n'avez pas encore ajouté Firebase à votre application, faites-le en suivant les étapes du 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, assurez-vous d'ouvrir votre projet Xcode à l'aide de son.xcworkspace
. - Dans votre application, importez Firebase :
Rapide
import Firebase
Objectif c
@import Firebase;
Directives relatives aux images d'entrée
Pour que ML Kit puisse lire avec précision les codes-barres, les images d'entrée doivent contenir des codes-barres représentés par suffisamment de données de pixels.
Les exigences spécifiques en matière de données de pixels dépendent à la fois du type de code-barres et de la quantité de données qui y sont codées (puisque la plupart des codes-barres prennent en charge 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 2 pixels (et pour les codes bidimensionnels, une hauteur de 2 pixels).
Par exemple, les codes-barres EAN-13 sont constitués de barres et d'espaces d'une largeur de 1, 2, 3 ou 4 unités. Une image de code-barres EAN-13 comporte donc idéalement des barres et des espaces d'au moins 2, 4, 6 et 8 pixels de large. Étant donné qu'un code-barres EAN-13 a une largeur totale de 95 unités, il doit avoir une largeur d'au moins 190 pixels.
Les formats plus denses, tels que PDF417, nécessitent des dimensions de pixels plus grandes pour que ML Kit puisse les lire de manière fiable. Par exemple, un code PDF417 peut contenir jusqu'à 34 « mots » de 17 unités de large sur une seule ligne, ce qui aurait idéalement une largeur d'au moins 1 156 pixels.
Une mauvaise mise au point 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 recapturer l'image.
Pour les applications typiques, il est recommandé de fournir une image de résolution plus élevée (telle que 1 280 x 720 ou 1 920 x 1 080), ce qui rend les codes-barres détectables à une plus grande distance de la caméra.
Cependant, 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 constitue la majorité de l'image d'entrée. Consultez également Conseils pour améliorer les performances en temps réel .
1. Configurez le détecteur de codes-barres
Si vous savez quels formats de codes-barres vous comptez lire, vous pouvez améliorer la vitesse du détecteur de codes-barres en le configurant pour détecter uniquement ces formats. Par exemple, pour détecter uniquement le code aztèque et les codes QR, créez un objet VisionBarcodeDetectorOptions
comme dans l'exemple suivant :
Rapide
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Les formats suivants sont pris en charge :
- Code128
- Code39
- Code93
- CodaBar
- EAN13
- EAN8
- FIT
- UPCA
- SEPC
- QR Code
- PDF417
- Aztèque
- Matrice de données
Objectif c
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Les formats suivants sont pris en charge :
- 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écutez le détecteur de codes-barres
Pour scanner les 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
:Rapide
lazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
Objectif 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 duUIImage
correctement pivoté. Ne spécifiez aucune métadonnée de rotation : la valeur par défaut,.topLeft
, doit être utilisée.Rapide
let image = VisionImage(image: uiImage)
Objectif c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
Pour utiliser un
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 :
Rapide
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 } }
Objectif 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; } }
Ensuite, créez l'objet de métadonnées :
Rapide
let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition )
Objectif 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 :Rapide
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objectif c
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Si nécessaire, faites pivoter l'image pour que sa propriété
- Ensuite, transmettez l'image à la méthode
detect(in:)
:Rapide
barcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... }
Objectif c
[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }];
3. Obtenez des informations à partir des codes-barres
Si l'opération de reconnaissance du code-barres réussit, 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 limites dans l'image d'entrée, ainsi que les données brutes codées par le code-barres. De plus, si le détecteur de code-barres a pu déterminer le type de données codées par le code-barres, vous pouvez obtenir un objet contenant des données analysées.Par exemple:
Rapide
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 } }
Objectif 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 directives pour obtenir les meilleures fréquences d'images :
Ne capturez pas l’entrée à la résolution native de la caméra. 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 très faible latence sans aucun avantage en termes de précision. Au lieu de cela, demandez uniquement à la caméra la taille requise pour la détection des codes-barres : généralement pas plus de 2 mégapixels.
Les préréglages de session de capture nommés
AVCaptureSessionPresetDefault
,AVCaptureSessionPresetLow
,AVCaptureSessionPresetMedium
, etc.) ne sont toutefois pas recommandés, car ils peuvent correspondre à des résolutions inappropriées sur certains appareils. Utilisez plutôt les 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. Cependant, gardez à l’esprit les exigences minimales en matière de taille de code-barres décrites ci-dessus.
- Accélérez les appels au détecteur. Si une nouvelle image vidéo devient disponible pendant le fonctionnement du détecteur, supprimez l'image.
- Si vous utilisez la sortie du détecteur pour superposer des graphiques sur l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis effectuez le rendu de l'image et la superposition en une seule étape. Ce faisant, vous effectuez le rendu sur la surface d'affichage une seule fois pour chaque image d'entrée. Consultez les classes previewOverlayView et FIRDetectionOverlayView dans l’exemple d’application de présentation pour un exemple.