Вы можете использовать ML Kit для распознавания и декодирования штрих-кодов.
Попробуйте это
- Поэкспериментируйте с примером приложения , чтобы увидеть пример использования этого API.
Прежде чем начать
-  Включите в свой подфайл следующие модули ML Kit:pod 'GoogleMLKit/BarcodeScanning', '8.0.0' 
- После установки или обновления модулей вашего проекта откройте проект Xcode, используя его .xcworkspace. ML Kit поддерживается в Xcode версии 12.4 или новее.
Рекомендации по входному изображению
- Чтобы 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-коды, создайте объект BarcodeScannerOptions , как показано в следующем примере: 
Быстрый
let format = .all let barcodeOptions = BarcodeScannerOptions(formats: format)
Поддерживаются следующие форматы:
- код128
- код39
- код93
- кодаБар
- dataMatrix
- EAN13
- EAN8
- МФТ
- qrCode
- УПКА
- УПЦЭ
- PDF417
- ацтекский
Цель-C
MLKBarcodeScannerOptions *options = [[MLKBarcodeScannerOptions alloc] initWithFormats: MLKBarcodeFormatQRCode | MLKBarcodeFormatAztec];
Поддерживаются следующие форматы:
-  Код-128 ( MLKBarcodeFormatCode128)
-  Код-39 ( MLKBarcodeFormatCode39)
-  Код-93 ( MLKBarcodeFormatCode93)
-  Кодабар ( MLKBarcodeFormatCodaBar)
-  Матрица данных ( MLKBarcodeFormatDataMatrix)
-  EAN-13 ( MLKBarcodeFormatEAN13)
-  EAN-8 ( MLKBarcodeFormatEAN8)
-  ITF ( MLKBarcodeFormatITF)
-  QR-код ( MLKBarcodeFormatQRCode)
-  UPC-A ( MLKBarcodeFormatUPCA)
-  UPC-E ( MLKBarcodeFormatUPCE)
-  PDF-417 ( MLKBarcodeFormatPDF417)
-  Ацтекский код ( MLKBarcodeFormatAztec)
2. Подготовьте входное изображение
Чтобы сканировать штрих-коды в изображении, передайте изображение какUIImage или CMSampleBufferRef в метод BarcodeScanner process() или results(in:) : Создайте объект VisionImage используя UIImage или CMSampleBuffer .
 Если вы используете UIImage , выполните следующие действия:
-  Создайте объект VisionImageс помощьюUIImage. Обязательно укажите правильную.orientation.Быстрыйlet image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation Цель-CMLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation; Если вы используете CMSampleBuffer, выполните следующие действия:- Укажите ориентацию данных изображения, содержащихся в - CMSampleBuffer.- Чтобы получить ориентацию изображения: - Быстрый- func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } } - Цель-C- - (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } } 
-  Создайте объект VisionImageиспользуя объектCMSampleBufferи ориентацию:Быстрыйlet image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition) Цель-CMLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition]; 3. Получите экземпляр BarcodeScanner.Получите экземплярBarcodeScanner:Быстрыйlet barcodeScanner = BarcodeScanner.barcodeScanner() // Or, to change the default settings: // let barcodeScanner = BarcodeScanner.barcodeScanner(options: barcodeOptions) Цель-CMLKBarcodeScanner *barcodeScanner = [MLKBarcodeScanner barcodeScanner]; // Or, to change the default settings: // MLKBarcodeScanner *barcodeScanner = // [MLKBarcodeScanner barcodeScannerWithOptions:options]; 4. Обработка изображенияЗатем передайте изображение вprocess():БыстрыйbarcodeScanner.process(visionImage) { features, error in guard error == nil, let features = features, !features.isEmpty else { // Error handling return } // Recognized barcodes } Цель-C[barcodeScanner processImage:image completion:^(NSArray<MLKBarcode *> *_Nullable barcodes, NSError *_Nullable error) { if (error != nil) { // Error handling return; } if (barcodes.count > 0) { // Recognized barcodes } }]; 5. Получите информацию из штрих-кодовЕсли операция сканирования штрих-кода прошла успешно, сканер возвращает массив объектовBarcode. Каждый объектBarcodeпредставляет собой штрих-код, обнаруженный на изображении. Для каждого штрих-кода вы можете получить его ограничивающие координаты во входном изображении, а также необработанные данные, закодированные штрих-кодом. Также, если сканер штрих-кода смог определить тип данных, закодированных штрих-кодом, вы можете получить объект, содержащий разобранные данные.Например: Быстрый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 } } Цель-Cfor (MLKBarcode *barcode in barcodes) { NSArray *corners = barcode.cornerPoints; NSString *displayValue = barcode.displayValue; NSString *rawValue = barcode.rawValue; MLKBarcodeValueType valueType = barcode.valueType; switch (valueType) { case MLKBarcodeValueTypeWiFi: ssid = barcode.wifi.ssid; password = barcode.wifi.password; encryptionType = barcode.wifi.type; break; case MLKBarcodeValueTypeURL: url = barcode.URL.url; title = barcode.URL.title; break; // ... default: break; } } Советы по повышению производительности в реальном времениЕсли вы хотите сканировать штрих-коды в приложении реального времени, следуйте этим рекомендациям для достижения наилучшей частоты кадров: - Не записывайте входные данные с собственным разрешением камеры. На некоторых устройствах при захвате входных данных с собственным разрешением создаются чрезвычайно большие (10+ мегапикселей) изображения, что приводит к очень низкой задержке без какого-либо улучшения точности. Вместо этого запрашивайте у камеры только тот размер, который необходим для сканирования штрих-кода, который обычно не превышает 2 мегапикселя. - Однако именованные предустановки сеанса захвата — - AVCaptureSessionPresetDefault,- AVCaptureSessionPresetLow,- AVCaptureSessionPresetMediumи т. д.) — не рекомендуются, поскольку они могут соответствовать неподходящим разрешениям на некоторых устройствах. Вместо этого используйте определенные пресеты, такие как- AVCaptureSessionPreset1280x720.- Если скорость сканирования важна, вы можете еще больше снизить разрешение захвата изображения. Однако помните о требованиях к минимальному размеру штрих-кода, изложенных выше. - Если вы пытаетесь распознать штрих-коды из последовательности кадров потокового видео, распознаватель может выдавать разные результаты от кадра к кадру. Вам следует подождать, пока вы не получите последовательные серии одного и того же значения, чтобы быть уверенным, что вы возвращаете хороший результат. - Цифра контрольной суммы не поддерживается для ITF и CODE-39. 
-  Для обработки видеокадров используйте синхронный API results(in:)детектора. Вызовите этот метод из функцииcaptureOutput(_, didOutput:from:)AVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты из данного видеокадра. Оставьте дляAVCaptureVideoDataOutputзначениеalwaysDiscardsLateVideoFramesкакtrue, чтобы ограничить вызовы детектора. Если во время работы детектора появится новый видеокадр, он будет удален.
- Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат из ML Kit, затем визуализируйте изображение и наложите его за один шаг. При этом вы выполняете рендеринг на поверхность дисплея только один раз для каждого обработанного входного кадра. Пример см. в updatePreviewOverlayViewWithLastFrame в образце быстрого запуска ML Kit.
 Если не указано иное, контент на этой странице предоставляется по лицензии Creative Commons "С указанием авторства 4.0", а примеры кода – по лицензии Apache 2.0. Подробнее об этом написано в правилах сайта. Java – это зарегистрированный товарный знак корпорации Oracle и ее аффилированных лиц. Последнее обновление: 2025-10-29 UTC. [null,null,["Последнее обновление: 2025-10-29 UTC."],[],[]]
 
