pdf_barcode_decoder 0.0.1
pdf_barcode_decoder: ^0.0.1 copied to clipboard
A fast, lightweight Flutter plugin to decode barcodes (QR, PDF417, Aztec, DataMatrix, Code128, etc.) directly from PDF files and bytes.
PDF Barcode Decoder #
A fast, lightweight, and offline Flutter plugin to scan and decode 1D & 2D barcodes directly from PDF files and raw bytes.
Under the hood, pdf_barcode_decoder renders PDF pages natively using Android PdfRenderer and Apple iOS PDFKit, then extracts barcodes using native, high-performance engines (ZXing Core on Android and Apple Vision Framework on iOS).
ð Key Features #
- ⥠Zero External Cloud/Network Dependencies â 100% offline, private, and on-device.
- ðŠķ Lightweight & Clean â Zero Google Play Services, ML Kit, or Firebase dependencies.
- ð Multiple Input Sources â Decode directly from
File, in-memoryUint8List, or bundled asset paths. - ðŊ Multi-Barcode Detection â Detects multiple barcodes on the same page with IoU-based deduplication.
- ð Precise Bounding Boxes â Returns exact pixel coordinates (
Rect) for bounding overlays and region cropping. - âïļ Configurable Pipeline â Control rendering resolution (DPI), page ranges (
maxPages,firstPageOnly), early stopping (stopAfterFirst), and barcode format filters. - ð Android 15 (16KB Page Size) Ready â Pure Java/Kotlin implementation without problematic C/C++ native binaries.
ðą Platform Support #
| Platform | Minimum OS Version | PDF Renderer | Barcode Engine | Notes |
|---|---|---|---|---|
| Android | Android 5.0 (API 21+) | android.graphics.pdf.PdfRenderer |
ZXing core:3.5.4 |
No Google Play Services required |
| iOS | iOS 13.0+ | PDFKit (PDFDocument) |
Vision.framework (VNDetectBarcodesRequest) |
System framework, zero CocoaPods dependencies |
ðĶ Supported Barcode Formats #
| Format Enum | Symbology / Barcode Type | Android (ZXing) | iOS (Vision) |
|---|---|---|---|
BarcodeFormat.qr |
QR Code | â | â |
BarcodeFormat.pdf417 |
PDF417 | â | â |
BarcodeFormat.aztec |
Aztec Code | â | â |
BarcodeFormat.dataMatrix |
DataMatrix | â | â |
BarcodeFormat.code128 |
Code 128 | â | â |
BarcodeFormat.ean13 |
EAN-13 | â | â |
BarcodeFormat.ean8 |
EAN-8 | â | â |
BarcodeFormat.upc |
UPC-A & UPC-E | â | â |
BarcodeFormat.itf |
Interleaved 2 of 5 (ITF) | â | â |
BarcodeFormat.codabar |
Codabar | â | â |
BarcodeFormat.all |
All supported formats | â | â |
ðïļ Architecture & How It Works #
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Flutter Application â
â PdfBarcodeDecoder.decode() / decodeFile() / decodeAsset() â
ââââââââââââââââââââââââââââââââŽâââââââââââââââââââââââââââââââ
â
Method Channel (decodePdf)
â
ââââââââââââââââââââīâââââââââââââââââââ
âž âž
âââââââââââââââââââââââââ âââââââââââââââââââââââââ
â Android Host â â iOS Host â
â (PdfDecodeManager) â â (PdfDecodeManager) â
âââââââââââââââââââââââââĪ âââââââââââââââââââââââââĪ
â 1. PdfRenderer â â 1. PDFKit â
â (Render at DPI) â â (Render at DPI) â
â 2. ZXing Core â â 2. Vision Framework â
â (MultiFormatReader)â â (DetectBarcodes) â
â 3. IoU Deduplication â â 3. Coordinate Scaling â
âââââââââââââŽââââââââââââ âââââââââââââŽââââââââââââ
â â
ââââââââââââââââââââŽâââââââââââââââââââ
âž
List<PdfBarcode> (with Page & Rect)
ðĨ Getting Started #
Add pdf_barcode_decoder to your pubspec.yaml dependencies:
dependencies:
pdf_barcode_decoder: ^0.0.1
Or run:
flutter pub add pdf_barcode_decoder
ðĄ Usage Examples #
1. Decode from a File (e.g. from file_picker or camera capture) #
import 'dart:io';
import 'package:pdf_barcode_decoder/pdf_barcode_decoder.dart';
Future<void> scanPdfFile(String filePath) async {
final file = File(filePath);
final List<PdfBarcode> barcodes = await PdfBarcodeDecoder.decodeFile(file);
for (final barcode in barcodes) {
print('Found ${barcode.type.name} on Page ${barcode.page + 1}: ${barcode.value}');
print('Bounding box: ${barcode.boundingBox}');
}
}
2. Decode from In-Memory Bytes (e.g. downloaded over HTTP) #
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:pdf_barcode_decoder/pdf_barcode_decoder.dart';
Future<void> scanPdfFromUrl(String url) async {
final response = await http.get(Uri.parse(url));
final Uint8List pdfBytes = response.bodyBytes;
final List<PdfBarcode> barcodes = await PdfBarcodeDecoder.decode(pdfBytes);
print('Found ${barcodes.length} barcode(s) in downloaded PDF.');
}
3. Decode from Bundled App Asset #
import 'package:pdf_barcode_decoder/pdf_barcode_decoder.dart';
Future<void> scanBundledPdf() async {
final List<PdfBarcode> barcodes = await PdfBarcodeDecoder.decodeAsset(
'assets/invoices/sample_invoice.pdf',
);
for (final b in barcodes) {
print('Barcode value: ${b.value}');
}
}
4. Advanced Configuration #
Fine-tune rendering quality, filter specific formats, scan only specific pages, or exit early:
import 'dart:io';
import 'package:pdf_barcode_decoder/pdf_barcode_decoder.dart';
final barcodes = await PdfBarcodeDecoder.decodeFile(
File('/path/to/shipping_label.pdf'),
config: const DecoderConfig(
// Rendering resolution (higher DPI = better recognition of small/dense barcodes)
dpi: 300,
// Scan only the first page
firstPageOnly: false,
// Exit immediately after finding the first barcode
stopAfterFirst: true,
// Scan up to the first 3 pages
maxPages: 3,
// Target specific barcode formats
formats: [
BarcodeFormat.qr,
BarcodeFormat.pdf417,
BarcodeFormat.code128,
],
),
);
5. Error Handling #
All platform and rendering errors are wrapped in a typed PdfBarcodeException:
import 'dart:io';
import 'package:pdf_barcode_decoder/pdf_barcode_decoder.dart';
try {
final barcodes = await PdfBarcodeDecoder.decodeFile(File('protected.pdf'));
} on PdfBarcodeException catch (e) {
switch (e.code) {
case 'ENCRYPTED_PDF':
print('Password-protected PDFs cannot be scanned.');
break;
case 'INVALID_PDF':
print('The provided file is corrupted or not a valid PDF.');
break;
case 'RENDER_FAILED':
print('Failed to render PDF pages: ${e.message}');
break;
default:
print('Decoding error [${e.code}]: ${e.message}');
}
}
ð API Reference #
DecoderConfig #
| Property | Type | Default | Description |
|---|---|---|---|
dpi |
int |
300 |
Resolution (DPI) at which PDF pages are rendered. Higher values improve detection on high-density 2D barcodes at the expense of memory. |
firstPageOnly |
bool |
false |
If true, only the first page (index 0) of the PDF is scanned. |
stopAfterFirst |
bool |
false |
If true, scanning halts immediately as soon as at least one barcode is detected. |
maxPages |
int? |
null |
Maximum number of pages to scan from the start of the document. If null, all pages are scanned. |
formats |
List<BarcodeFormat> |
[BarcodeFormat.all] |
Restricts detection to specified symbologies. |
PdfBarcode #
| Property | Type | Description |
|---|---|---|
type |
BarcodeFormat |
The detected barcode symbology (e.g. BarcodeFormat.qr, BarcodeFormat.pdf417). |
value |
String |
The raw decoded string value of the barcode. |
page |
int |
The 0-indexed page number where the barcode was found. |
boundingBox |
Rect |
The bounding box coordinates (in pixel space at the configured render DPI) locating the barcode on the page. |
⥠Performance & Best Practices #
- Choosing the Optimal DPI:
150 DPIâ Fast; suitable for large standard QR codes and shipping label barcodes.300 DPI(Default) â Recommended balance for crisp renders, PDF417 boarding passes, and multi-code documents.400+ DPIâ Use when barcodes are physically tiny or high-density DataMatrix codes.
- Page Limits: For long documents (e.g., 50+ page invoices), always supply
maxPagesorstopAfterFirst: trueif you only need the header barcode. - Memory Management: Both native Android and iOS engines recycle page bitmaps and autorelease pools after each page scan to ensure low memory footprints.
ðą Example App #
Check the example/ folder for a complete sample Flutter app demonstrating PDF picking, asset scanning, and real-time result listing.
To run the example app:
cd example
flutter run
ðĪ Contributing #
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.
ð License #
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.