Реализация генерации штрих-кодов в мобильном приложении
Потребность появляется неожиданно: склад хочет печатать этикетки прямо с телефона, торговая точка — генерировать QR-чеки офлайн, логистическое приложение — создавать Code128 для накладных без обращения к серверу. Казалось бы, мелкая задача, но неправильный выбор библиотеки выстреливает проблемами позже.
Какие форматы реально нужны и чем их генерировать
Линейные штрих-коды — EAN-13, EAN-8, UPC-A, Code128, Code39, ITF — используют разные алгоритмы контрольной суммы. Путать их нельзя: ретейлеры сканируют EAN-13, а курьерские службы — Code128 с символами произвольного набора. QR-код и Data Matrix закрывают двумерные сценарии.
iOS. Нативно CoreImage умеет генерировать QR (CIQRCodeGenerator), Aztec, Code128 и PDF417. Для EAN/UPC проще взять ZXingObjC или обёртку поверх ZXing — она охватывает все форматы сразу. Рендерим в CIImage, масштабируем через CGAffineTransform (без интерполяции, иначе края пикселей размываются), экспортируем в PNG через UIGraphicsImageRenderer.
Android. ZXing (com.google.zxing:core:3.5.x) — стандарт де-факто. MultiFormatWriter.encode() возвращает BitMatrix, рисуем в Bitmap через MatrixToImageWriter или вручную итерируя пиксели. Для Jetpack Compose — оборачиваем в AndroidView с ImageView, либо используем BarcodeEncoder из journeyapps/zxing-android-embedded.
Flutter. barcode_widget (pub.dev) рисует через Canvas без нативного кода. Для вывода в файл — toImage() через RepaintBoundary + RenderRepaintBoundary.toImage(pixelRatio: 3.0).
Типичные грабли
Масштабирование без interpolationQuality = .none (iOS) даёт размытые края — сканер их не читает. На Android аналогичная ошибка: Bitmap.createScaledBitmap(..., true) с включённой фильтрацией уничтожает чёткость линий Code128 при небольших размерах.
Контрастность: чёрный на белом — это не «по умолчанию хорошо». При выводе на тёмном фоне приложения нужно явно задавать цвета fgColor/bgColor. QR на прозрачном фоне не читается большинством сканеров в неблагоприятном освещении.
Минимальный размер QR-кода с коррекцией ошибок уровня M — 150×150 dp. Ниже — проблемы на дешёвых Android-устройствах с 8 Мп камерой.
Динамический контент и пакетная генерация
Штрих-коды чаще генерируются не статически, а «на лету» из данных: артикул товара, номер заказа, идентификатор пользователя. Шаблонный подход: String.format("ORDER-%06d", orderId) → кодируем → рендерим. Для массового создания (пример: 500 этикеток перед отгрузкой) генерируем в фоновом потоке DispatchQueue.global() / Executors.newFixedThreadPool(4) и отображаем прогресс.
Если нужен штрих-код в PDF-документе — интегрируем генерацию с PDFKit (iOS) / android.graphics.pdf.PdfDocument (Android): рисуем Bitmap штрих-кода напрямую на PdfDocument.Page.getCanvas().
Сохранение и шаринг
Генерируем в Bitmap/UIImage, сохраняем во временный файл через FileProvider (Android) или UIActivityViewController (iOS). Для Flutter — path_provider + share_plus. При печати через Bluetooth-принтер (Zebra ZPL, Citizen) передаём ZPL-команду напрямую, не растровое изображение — это даёт чёткость на любом DPI.
Сроки
Реализация генерации 2-3 форматов с экраном просмотра и кнопкой шаринга — 1 рабочий день. Если нужна интеграция с принтером или пакетная генерация с шаблонами — 2-3 дня.







