Вы можете использовать ML Kit для распознавания и декодирования штрих-кодов.
Прежде чем начать
- Если вы еще не добавили Firebase в свое приложение, сделайте это, выполнив действия, описанные в руководстве по началу работы .
-  Включите библиотеки ML Kit в свой подфайл:pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarcodeModel' .xcworkspace.
-  Импортируйте Firebase в свое приложение: Быстрыйimport Firebase Цель-C@import Firebase; 
Рекомендации по входному изображению
- Чтобы ML Kit мог точно считывать штрих-коды, входные изображения должны содержать штрих-коды, представленные достаточным количеством пиксельных данных. - Конкретные требования к пиксельным данным зависят как от типа штрих-кода, так и от объема данных, которые в нем закодированы (поскольку большинство штрих-кодов поддерживают полезную нагрузку переменной длины). Как правило, наименьшая значимая единица штрих-кода должна иметь ширину не менее 2 пикселей (а для двумерных кодов — высоту 2 пикселя). - Например, штрих-коды EAN-13 состоят из полос и пробелов шириной 1, 2, 3 или 4 единицы, поэтому изображение штрих-кода EAN-13 в идеале содержит полосы и пробелы длиной не менее 2, 4, 6 и более. Ширина 8 пикселей. Поскольку общая ширина штрих-кода EAN-13 составляет 95 единиц, ширина штрих-кода должна быть не менее 190 пикселей. - Более плотные форматы, такие как PDF417, требуют большего размера в пикселях, чтобы ML Kit мог их надежно читать. Например, код PDF417 может содержать до 34 «слов» шириной 17 единиц в одной строке, которая в идеале должна иметь ширину не менее 1156 пикселей. 
- Плохая фокусировка изображения может снизить точность сканирования. Если вы не получили приемлемых результатов, попробуйте попросить пользователя повторно сделать снимок. 
- Для типичных приложений рекомендуется предоставлять изображение с более высоким разрешением (например, 1280x720 или 1920x1080), что позволяет обнаруживать штрих-коды на большем расстоянии от камеры. - Однако в приложениях, где задержка имеет решающее значение, вы можете повысить производительность, захватывая изображения с более низким разрешением, но требуя, чтобы штрих-код составлял большую часть входного изображения. Также см . Советы по повышению производительности в реальном времени . 
1. Настройте детектор штрих-кода
Если вы знаете, какие форматы штрих-кодов вы собираетесь считывать, вы можете повысить скорость детектора штрих-кодов, настроив его на обнаружение только этих форматов. Например, чтобы обнаружить только ацтекский код и QR-коды, создайте объект VisionBarcodeDetectorOptions , как показано в следующем примере: 
Быстрый
let format = VisionBarcodeFormat.all let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
Поддерживаются следующие форматы:
- Код128
- Код39
- Код93
- КодаБар
- EAN13
- EAN8
- МФТ
- УПКА
- УПЦЭ
- QR-код
- PDF417
- ацтекский
- ДатаМатрикс
Цель-C
FIRVisionBarcodeDetectorOptions *options = [[FIRVisionBarcodeDetectorOptions alloc] initWithFormats: FIRVisionBarcodeFormatQRCode | FIRVisionBarcodeFormatAztec];
Поддерживаются следующие форматы:
-  Код 128 ( FIRVisionBarcodeFormatCode128)
-  Код 39 ( FIRVisionBarcodeFormatCode39)
-  Код 93 ( FIRVisionBarcodeFormatCode93)
-  Кодабар ( FIRVisionBarcodeFormatCodaBar)
-  EAN-13 ( FIRVisionBarcodeFormatEAN13)
-  EAN-8 ( FIRVisionBarcodeFormatEAN8)
-  ITF ( FIRVisionBarcodeFormatITF)
-  UPC-A ( FIRVisionBarcodeFormatUPCA)
-  UPC-E ( FIRVisionBarcodeFormatUPCE)
-  QR-код ( FIRVisionBarcodeFormatQRCode)
-  PDF417 ( FIRVisionBarcodeFormatPDF417)
-  Ацтекский ( FIRVisionBarcodeFormatAztec)
-  Матрица данных ( FIRVisionBarcodeFormatDataMatrix)
2. Запустите детектор штрих-кода
Чтобы сканировать штрих-коды в изображении, передайте изображение какUIImage или CMSampleBufferRef в метод detect(in:) VisionBarcodeDetector :-  Получите экземпляр VisionBarcodeDetector:Быстрыйlazy var vision = Vision.vision() let barcodeDetector = vision.barcodeDetector(options: barcodeOptions) Цель-CFIRVision *vision = [FIRVision vision]; FIRVisionBarcodeDetector *barcodeDetector = [vision barcodeDetector]; // Or, to change the default settings: // FIRVisionBarcodeDetector *barcodeDetector = // [vision barcodeDetectorWithOptions:options]; 
- Создайте объект - VisionImageиспользуя- UIImageили- CMSampleBufferRef.- Чтобы использовать - UIImage:-  При необходимости поверните изображение так, чтобы его свойство imageOrientationимело значение.up.
-  Создайте объект VisionImageиспользуя правильно повернутыйUIImage. Не указывайте метаданные вращения — необходимо использовать значение по умолчанию.topLeft.Быстрыйlet image = VisionImage(image: uiImage) Цель-CFIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage]; 
 - Чтобы использовать - CMSampleBufferRef:- Создайте объект - VisionImageMetadata, который задает ориентацию данных изображения, содержащихся в буфере- CMSampleBufferRef.- Чтобы получить ориентацию изображения: - Быстрый- 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 } } - Цель-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; } } - Затем создайте объект метаданных: - Быстрый- let cameraPosition = AVCaptureDevice.Position.back // Set to the capture device you used. let metadata = VisionImageMetadata() metadata.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition ) - Цель-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]; 
-  Создайте объект VisionImageиспользуя объектCMSampleBufferRefи метаданные вращения:Быстрыйlet image = VisionImage(buffer: sampleBuffer) image.metadata = metadata Цель-CFIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata; 
 
-  При необходимости поверните изображение так, чтобы его свойство 
-  Затем передайте изображение методу detect(in:):БыстрыйbarcodeDetector.detect(in: visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // ... return } // ... } Цель-C[barcodeDetector detectInImage:image completion:^(NSArray<FIRVisionBarcode *> *barcodes, NSError *error) { if (error != nil) { return; } else if (barcodes != nil) { // Recognized barcodes // ... } }]; 
3. Получите информацию из штрих-кодов
Если операция распознавания штрих-кода прошла успешно, детектор возвращает массив объектовVisionBarcode . Каждый объект VisionBarcode представляет штрих-код, обнаруженный на изображении. Для каждого штрих-кода вы можете получить его ограничивающие координаты во входном изображении, а также необработанные данные, закодированные штрих-кодом. Также, если детектор штрих-кода смог определить тип данных, закодированных штрих-кодом, можно получить объект, содержащий разобранные данные.Например:
Быстрый
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 } }
Цель-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; } }
Советы по повышению производительности в реальном времени
Если вы хотите сканировать штрих-коды в приложении реального времени, следуйте этим рекомендациям для достижения наилучшей частоты кадров:
- Не записывайте входные данные с собственным разрешением камеры. На некоторых устройствах при захвате входных данных с собственным разрешением создаются чрезвычайно большие (10+ мегапикселей) изображения, что приводит к очень низкой задержке без какого-либо улучшения точности. Вместо этого запрашивайте у камеры только тот размер, который необходим для обнаружения штрих-кода: обычно не более 2 мегапикселей. - Однако именованные предустановки сеанса захвата — - AVCaptureSessionPresetDefault,- AVCaptureSessionPresetLow,- AVCaptureSessionPresetMediumи т. д.) — не рекомендуются, поскольку они могут соответствовать неподходящим разрешениям на некоторых устройствах. Вместо этого используйте определенные пресеты, такие как- AVCaptureSessionPreset1280x720.- Если скорость сканирования важна, вы можете еще больше снизить разрешение захвата изображения. Однако помните о требованиях к минимальному размеру штрих-кода, изложенных выше. 
- Дроссель вызывает детектор. Если новый видеокадр становится доступным во время работы детектора, удалите этот кадр.
- Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат из ML Kit, затем визуализируйте изображение и наложите его за один шаг. При этом вы выполняете рендеринг на поверхность дисплея только один раз для каждого входного кадра. Пример см. в классах PreviewOverlayView и FIRDetectionOverlayView в демонстрационном примере приложения.