From d0fc094106f81b80e6e808fedff20cb30a8afc10 Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Mon, 9 May 2022 12:30:02 +0400 Subject: [PATCH] allow to read barcode from image --- example/ios/Podfile.lock | 35 ++++++ example/lib/pages/creator_page.dart | 158 +++++----------------------- example/lib/pages/history_page.dart | 141 +------------------------ example/lib/pages/scanner_page.dart | 86 +++++++-------- example/pubspec.lock | 44 +++++++- example/pubspec.yaml | 1 + ios/Classes/src/native_zxing.cpp | 49 ++++++++- ios/Classes/src/native_zxing.h | 19 +++- lib/flutter_zxing.dart | 28 +++-- lib/generated_bindings.dart | 76 ++++++++++--- lib/isolate_utils.dart | 2 +- lib/zxing_reader_widget.dart | 1 - lib/zxing_writer_widget.dart | 7 +- pubspec.yaml | 2 +- 14 files changed, 297 insertions(+), 352 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b6a2958..0d03d3e 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,50 +1,85 @@ PODS: - camera (0.0.1): - Flutter + - connectivity_plus (0.0.1): + - Flutter + - ReachabilitySwift - Flutter (1.0.0) - flutter_beep (0.0.1): - Flutter - flutter_zxing (0.0.1): - Flutter + - fluttertoast (0.0.2): + - Flutter + - Toast + - nb_utils (0.0.1): + - Flutter - path_provider_ios (0.0.1): - Flutter + - ReachabilitySwift (5.0.0) - share_plus (0.0.1): - Flutter + - shared_preferences_ios (0.0.1): + - Flutter + - Toast (4.0.0) - url_launcher_ios (0.0.1): - Flutter DEPENDENCIES: - camera (from `.symlinks/plugins/camera/ios`) + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - Flutter (from `Flutter`) - flutter_beep (from `.symlinks/plugins/flutter_beep/ios`) - flutter_zxing (from `.symlinks/plugins/flutter_zxing/ios`) + - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - nb_utils (from `.symlinks/plugins/nb_utils/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) +SPEC REPOS: + trunk: + - ReachabilitySwift + - Toast + EXTERNAL SOURCES: camera: :path: ".symlinks/plugins/camera/ios" + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" Flutter: :path: Flutter flutter_beep: :path: ".symlinks/plugins/flutter_beep/ios" flutter_zxing: :path: ".symlinks/plugins/flutter_zxing/ios" + fluttertoast: + :path: ".symlinks/plugins/fluttertoast/ios" + nb_utils: + :path: ".symlinks/plugins/nb_utils/ios" path_provider_ios: :path: ".symlinks/plugins/path_provider_ios/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" + shared_preferences_ios: + :path: ".symlinks/plugins/shared_preferences_ios/ios" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: camera: 9993f92f2c793e87b65e35f3a23c70582afb05b1 + connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a flutter_beep: 54fb393b22dfa0f0e4573c81b1c74dd71c4e5af8 flutter_zxing: 19a866d17c8a87ee1026d68521c69d2f008635f6 + fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037 + nb_utils: ada4338858d8827ec92fdab2a545206b4ba4cfb1 path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 + shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad + Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c diff --git a/example/lib/pages/creator_page.dart b/example/lib/pages/creator_page.dart index 7fe6af1..8f2955f 100644 --- a/example/lib/pages/creator_page.dart +++ b/example/lib/pages/creator_page.dart @@ -1,13 +1,8 @@ import 'dart:io'; import 'dart:typed_data'; -import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:flutter_zxing/generated_bindings.dart'; -import 'package:flutter_zxing/zxing_reader_widget.dart'; -import 'package:flutter_zxing/zxing_writer_widget.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; @@ -23,22 +18,12 @@ class CreatorPage extends StatefulWidget { State createState() => _CreatorPageState(); } -class _CreatorPageState extends State - with TickerProviderStateMixin { - CameraController? controller; - TabController? _tabController; - +class _CreatorPageState extends State { bool isAndroid() => Theme.of(context).platform == TargetPlatform.android; - // Scan result queue - final _resultQueue = []; - // Write result Uint8List? writeResult; - // true when the camera is active - bool _isScanning = true; - @override void initState() { super.initState(); @@ -47,92 +32,47 @@ class _CreatorPageState extends State } void initStateAsync() async { - _tabController = TabController(length: 3, vsync: this); - _tabController?.addListener(() { - _isScanning = _tabController?.index == 0; - if (_isScanning) { - controller?.resumePreview(); - } else { - controller?.pausePreview(); - } - }); getTemporaryDirectory().then((value) { tempDir = value; }); } - @override - void dispose() { - super.dispose(); - controller?.dispose(); - } - - void showInSnackBar(String message) {} - - void logError(String code, String? message) { - if (message != null) { - debugPrint('Error: $code\nError Message: $message'); - } else { - debugPrint('Error: $code'); - } - } - @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Creator'), - bottom: TabBar( - controller: _tabController, - tabs: const [ - Tab(text: 'Scanner'), - Tab(text: 'Result'), - Tab(text: 'Writer'), - ], - ), ), - body: TabBarView( - controller: _tabController, - children: [ - // Scanner - ZxingReaderWidget(onScan: (result) async { - _resultQueue.insert(0, result); - _tabController?.index = 1; - await Future.delayed(const Duration(milliseconds: 500)); - setState(() {}); - }), - // Result - _buildResultList(), - // Writer - SingleChildScrollView( - child: Column( - children: [ - ZxingWriterWidget( - onSuccess: (result) { - setState(() { - writeResult = result; - }); - }, - onError: (error) { - setState(() { - writeResult = null; - }); - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - error, - textAlign: TextAlign.center, - ), + body: SingleChildScrollView( + child: Column( + children: [ + ZxingWriterWidget( + onSuccess: (result) { + setState(() { + writeResult = result; + }); + }, + onError: (error) { + setState(() { + writeResult = null; + }); + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Padding( + padding: const EdgeInsets.only(bottom: 30.0), + child: Text( + error, + textAlign: TextAlign.center, ), - ); - }, - ), - if (writeResult != null) buildWriteResult(), - ], + ), + ), + ); + }, ), - ), - ], + if (writeResult != null) buildWriteResult(), + ], + ), ), ); } @@ -157,44 +97,4 @@ class _CreatorPageState extends State ], ); } - - _buildResultList() { - return _resultQueue.isEmpty - ? const Center( - child: Text( - 'No Results', - style: TextStyle(fontSize: 24), - )) - : ListView.builder( - itemCount: _resultQueue.length, - itemBuilder: (context, index) { - final result = _resultQueue[index]; - return ListTile( - title: Text(result.textString), - subtitle: Text(result.formatString), - trailing: ButtonBar( - mainAxisSize: MainAxisSize.min, - children: [ - // Copy button - TextButton( - child: const Text('Copy'), - onPressed: () { - Clipboard.setData( - ClipboardData(text: result.textString)); - }, - ), - // Remove button - IconButton( - icon: const Icon(Icons.delete, color: Colors.red), - onPressed: () { - _resultQueue.removeAt(index); - setState(() {}); - }, - ), - ], - ), - ); - }, - ); - } } diff --git a/example/lib/pages/history_page.dart b/example/lib/pages/history_page.dart index 8621f10..e01b8a5 100644 --- a/example/lib/pages/history_page.dart +++ b/example/lib/pages/history_page.dart @@ -1,18 +1,6 @@ -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:flutter_zxing/generated_bindings.dart'; -import 'package:flutter_zxing/zxing_reader_widget.dart'; -import 'package:flutter_zxing/zxing_writer_widget.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:share_plus/share_plus.dart'; - -late Directory tempDir; -String get tempPath => '${tempDir.path}/zxing.jpg'; class HistoryPage extends StatefulWidget { const HistoryPage({ @@ -23,137 +11,16 @@ class HistoryPage extends StatefulWidget { State createState() => _HistoryPageState(); } -class _HistoryPageState extends State with TickerProviderStateMixin { - CameraController? controller; - TabController? _tabController; - - bool isAndroid() => Theme.of(context).platform == TargetPlatform.android; - - // Scan result queue +class _HistoryPageState extends State { final _resultQueue = []; - // Write result - Uint8List? writeResult; - - // true when the camera is active - bool _isScanning = true; - - @override - void initState() { - super.initState(); - - initStateAsync(); - } - - void initStateAsync() async { - _tabController = TabController(length: 3, vsync: this); - _tabController?.addListener(() { - _isScanning = _tabController?.index == 0; - if (_isScanning) { - controller?.resumePreview(); - } else { - controller?.pausePreview(); - } - }); - getTemporaryDirectory().then((value) { - tempDir = value; - }); - } - - @override - void dispose() { - super.dispose(); - controller?.dispose(); - } - - void showInSnackBar(String message) {} - - void logError(String code, String? message) { - if (message != null) { - debugPrint('Error: $code\nError Message: $message'); - } else { - debugPrint('Error: $code'); - } - } - @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Flutter Scanner'), - bottom: TabBar( - controller: _tabController, - tabs: const [ - Tab(text: 'Scanner'), - Tab(text: 'Result'), - Tab(text: 'Writer'), - ], - ), + title: const Text('History'), ), - body: TabBarView( - controller: _tabController, - children: [ - // Scanner - ZxingReaderWidget(onScan: (result) async { - _resultQueue.insert(0, result); - _tabController?.index = 1; - await Future.delayed(const Duration(milliseconds: 500)); - setState(() {}); - }), - // Result - _buildResultList(), - // Writer - SingleChildScrollView( - child: Column( - children: [ - ZxingWriterWidget( - onSuccess: (result) { - setState(() { - writeResult = result; - }); - }, - onError: (error) { - setState(() { - writeResult = null; - }); - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - error, - textAlign: TextAlign.center, - ), - ), - ); - }, - ), - if (writeResult != null) buildWriteResult(), - ], - ), - ), - ], - ), - ); - } - - Column buildWriteResult() { - return Column( - children: [ - // Barcode image - Image.memory(writeResult ?? Uint8List(0)), - // Share button - ElevatedButton( - onPressed: () { - // Save image to device - final file = File(tempPath); - file.writeAsBytesSync(writeResult ?? Uint8List(0)); - final path = file.path; - // Share image - Share.shareFiles([path]); - }, - child: const Text('Share'), - ), - ], + body: _buildResultList(), ); } @@ -169,7 +36,7 @@ class _HistoryPageState extends State with TickerProviderStateMixin itemBuilder: (context, index) { final result = _resultQueue[index]; return ListTile( - title: Text(result.textString), + title: Text(result.textString ?? ''), subtitle: Text(result.formatString), trailing: ButtonBar( mainAxisSize: MainAxisSize.min, diff --git a/example/lib/pages/scanner_page.dart b/example/lib/pages/scanner_page.dart index 05f0ebb..f3eadd3 100644 --- a/example/lib/pages/scanner_page.dart +++ b/example/lib/pages/scanner_page.dart @@ -1,5 +1,10 @@ +import 'dart:typed_data'; + import 'package:flutter/material.dart'; -import 'package:flutter_zxing/zxing_reader_widget.dart'; +import 'package:flutter_zxing/flutter_zxing.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:image/image.dart' as imglib; class ScannerPage extends StatefulWidget { const ScannerPage({ @@ -10,60 +15,45 @@ class ScannerPage extends StatefulWidget { State createState() => _ScannerPageState(); } -class _ScannerPageState extends State - with TickerProviderStateMixin { - TabController? _tabController; - - @override - void initState() { - super.initState(); - - initStateAsync(); - } - - void initStateAsync() async { - _tabController = TabController(length: 3, vsync: this); - } - - @override - void dispose() { - super.dispose(); - _tabController?.dispose(); - } +class _ScannerPageState extends State { + final ImagePicker _picker = ImagePicker(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Scanner'), - bottom: TabBar( - controller: _tabController, - tabs: const [ - Tab(text: 'Single code'), - Tab(text: 'Multi code'), - Tab(text: 'Image'), - ], - ), ), - body: TabBarView( - controller: _tabController, - children: [ - // Single code scanner - ZxingReaderWidget(onScan: (result) async { - // _resultQueue.insert(0, result); - // await Future.delayed(const Duration(milliseconds: 500)); - // setState(() {}); - }), - // Multi code scanner - Container(), - // ZxingReaderWidget(onScan: (result) async { - // // _resultQueue.insert(0, result); - // // await Future.delayed(const Duration(milliseconds: 500)); - // // setState(() {}); - // }), - // Image scanner - Container(), - ], + body: ZxingReaderWidget( + onScan: (result) async { + // _resultQueue.insert(0, result); + // await Future.delayed(const Duration(milliseconds: 500)); + // setState(() {}); + }, + ), + floatingActionButton: FloatingActionButton( + child: const Icon(FontAwesomeIcons.image), + onPressed: () async { + final XFile? file = + await _picker.pickImage(source: ImageSource.gallery); + if (file != null) { + final Uint8List bytes = await file.readAsBytes(); + imglib.Image? image = imglib.decodeImage(bytes); + if (image != null) { + final CodeResult result = FlutterZxing.readBarcode( + image.getBytes(format: imglib.Format.luminance), + Format.Any, + image.width, + image.height, + 0, + 0, + ); + if (result.isValidBool) { + debugPrint(result.textString); + } + } + } + }, ), ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index a4622ad..d30b13f 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -105,7 +105,7 @@ packages: name: camera url: "https://pub.dartlang.org" source: hosted - version: "0.9.4+19" + version: "0.9.4+21" camera_platform_interface: dependency: transitive description: @@ -378,6 +378,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" http_multi_server: dependency: transitive description: @@ -399,6 +406,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.3" + image_picker: + dependency: "direct main" + description: + name: image_picker + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.4+11" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.6" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.5" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.4" intl: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 7fd9ee6..cd27528 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: flutter_zxing: path: ../ font_awesome_flutter: ^10.1.0 + image_picker: ^0.8.5 nb_utils: ^4.5.0 path_provider: ^2.0.9 share_plus: ^4.0.4 diff --git a/ios/Classes/src/native_zxing.cpp b/ios/Classes/src/native_zxing.cpp index 2caac47..ca5c93e 100644 --- a/ios/Classes/src/native_zxing.cpp +++ b/ios/Classes/src/native_zxing.cpp @@ -10,13 +10,13 @@ using namespace ZXing; extern "C" { FUNCTION_ATTRIBUTE - char *zxingVersion() + char *version() { return "1.3.0"; } FUNCTION_ATTRIBUTE - struct CodeResult zxingRead(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled) + struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled) { long long start = get_now(); @@ -52,7 +52,50 @@ extern "C" } FUNCTION_ATTRIBUTE - struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled) + struct CodeResult* readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled) + { + long long start = get_now(); + + long length = width * height; + uint8_t *data = new uint8_t[length]; + memcpy(data, bytes, length); + + BarcodeFormats formats = BarcodeFormat(format); // BarcodeFormat::Any; + DecodeHints hints = DecodeHints().setTryHarder(false).setTryRotate(true).setFormats(formats); + ImageView image{data, width, height, ImageFormat::Lum}; + if (cropWidth > 0 && cropHeight > 0 && cropWidth < width && cropHeight < height) + { + image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight); + } + Results results = ReadBarcodes(image, hints); + + struct CodeResult *codes = new struct CodeResult [results.size()]; + int i = 0; + for (auto &result : results) + { + struct CodeResult code = {false, nullptr}; + if (result.isValid()) + { + code.isValid = result.isValid(); + code.text = new char[result.text().length() + 1]; + std::string text = std::string(result.text().begin(), result.text().end()); + strcpy(code.text, text.c_str()); + code.format = Format(static_cast(result.format())); + codes[i] = code; + i++; + } + } + + int evalInMillis = static_cast(get_now() - start); + if (logEnabled) + { + platform_log("zxingRead: %d ms", evalInMillis); + } + return codes; + } + + FUNCTION_ATTRIBUTE + struct EncodeResult encodeBarcode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled) { long long start = get_now(); diff --git a/ios/Classes/src/native_zxing.h b/ios/Classes/src/native_zxing.h index 890efa5..9a6b840 100644 --- a/ios/Classes/src/native_zxing.h +++ b/ios/Classes/src/native_zxing.h @@ -48,7 +48,7 @@ extern "C" * * @return The version of the zxing library. */ - char *zxingVersion(); + char *version(); /** * @brief Reads barcode from image. @@ -61,7 +61,20 @@ extern "C" * @param logEnabled Log enabled. * @return Barcode result. */ - struct CodeResult zxingRead(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled); + struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled); + + /** + * @brief Reads barcodes from image. + * @param bytes Image bytes. + * @param format The format of the barcode + * @param width Image width. + * @param height Image height. + * @param cropWidth Crop width. + * @param cropHeight Crop height. + * @param logEnabled Log enabled. + * @return Barcode results. + */ + struct CodeResult* readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled); /** * @brief Encode a string into a barcode @@ -74,7 +87,7 @@ extern "C" * @param eccLevel The error correction level of the barcode. Used for Aztec, PDF417, and QRCode only, [0-8]. * @return The barcode data */ - struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled); + struct EncodeResult encodeBarcode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled); #ifdef __cplusplus } diff --git a/lib/flutter_zxing.dart b/lib/flutter_zxing.dart index 9bc50ab..89fc9c5 100644 --- a/lib/flutter_zxing.dart +++ b/lib/flutter_zxing.dart @@ -4,10 +4,15 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:ffi/ffi.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'generated_bindings.dart'; +export 'generated_bindings.dart'; +export 'zxing_reader_widget.dart'; +export 'zxing_writer_widget.dart'; + class FlutterZxing { static const MethodChannel _channel = MethodChannel('flutter_zxing'); @@ -20,19 +25,27 @@ class FlutterZxing { static bool logEnabled = true; - static String zxingVersion() { - return bindings.zxingVersion().cast().toDartString(); + static String version() { + return bindings.version().cast().toDartString(); } - static CodeResult zxingRead(Uint8List bytes, int format, int width, + static CodeResult readBarcode(Uint8List bytes, int format, int width, int height, int cropWidth, int cropHeight) { - return bindings.zxingRead(bytes.allocatePointer(), format, width, height, + return bindings.readBarcode(bytes.allocatePointer(), format, width, height, cropWidth, cropHeight, _logEnabled); } - static EncodeResult zxingEncode(String contents, int width, int height, + static List readBarcodes(Uint8List bytes, int format, int width, + int height, int cropWidth, int cropHeight) { + final result = bindings.readBarcodes(bytes.allocatePointer(), format, width, + height, cropWidth, cropHeight, _logEnabled); + debugPrint(result.toString()); + return []; + } + + static EncodeResult encodeBarcode(String contents, int width, int height, int format, int margin, int eccLevel) { - var result = bindings.zxingEncode(contents.toNativeUtf8().cast(), + var result = bindings.encodeBarcode(contents.toNativeUtf8().cast(), width, height, format, margin, eccLevel, _logEnabled); return result; } @@ -70,7 +83,8 @@ extension Encode on EncodeResult { extension Code on CodeResult { bool get isValidBool => isValid == 1; - String get textString => text.cast().toDartString(); + String? get textString => + text == nullptr ? null : text.cast().toDartString(); String get formatString { return CodeFormat.formatName(format); diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart index d65b1dc..019b164 100644 --- a/lib/generated_bindings.dart +++ b/lib/generated_bindings.dart @@ -22,15 +22,14 @@ class GeneratedBindings { /// Returns the version of the zxing library. /// /// @return The version of the zxing library. - ffi.Pointer zxingVersion() { - return _zxingVersion(); + ffi.Pointer version() { + return _version(); } - late final _zxingVersionPtr = - _lookup Function()>>( - 'zxingVersion'); - late final _zxingVersion = - _zxingVersionPtr.asFunction Function()>(); + late final _versionPtr = + _lookup Function()>>('version'); + late final _version = + _versionPtr.asFunction Function()>(); /// @brief Reads barcode from image. /// @param bytes Image bytes. @@ -41,7 +40,7 @@ class GeneratedBindings { /// @param cropHeight Crop height. /// @param logEnabled Log enabled. /// @return Barcode result. - CodeResult zxingRead( + CodeResult readBarcode( ffi.Pointer bytes, int format, int width, @@ -50,7 +49,7 @@ class GeneratedBindings { int cropHeight, int logEnabled, ) { - return _zxingRead( + return _readBarcode( bytes, format, width, @@ -61,14 +60,57 @@ class GeneratedBindings { ); } - late final _zxingReadPtr = _lookup< + late final _readBarcodePtr = _lookup< ffi.NativeFunction< CodeResult Function(ffi.Pointer, ffi.Int32, ffi.Int32, - ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('zxingRead'); - late final _zxingRead = _zxingReadPtr.asFunction< + ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('readBarcode'); + late final _readBarcode = _readBarcodePtr.asFunction< CodeResult Function( ffi.Pointer, int, int, int, int, int, int)>(); + /// @brief Reads barcodes from image. + /// @param bytes Image bytes. + /// @param format The format of the barcode + /// @param width Image width. + /// @param height Image height. + /// @param cropWidth Crop width. + /// @param cropHeight Crop height. + /// @param logEnabled Log enabled. + /// @return Barcode results. + ffi.Pointer readBarcodes( + ffi.Pointer bytes, + int format, + int width, + int height, + int cropWidth, + int cropHeight, + int logEnabled, + ) { + return _readBarcodes( + bytes, + format, + width, + height, + cropWidth, + cropHeight, + logEnabled, + ); + } + + late final _readBarcodesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Int32, + ffi.Int32, + ffi.Int32, + ffi.Int32, + ffi.Int32, + ffi.Int32)>>('readBarcodes'); + late final _readBarcodes = _readBarcodesPtr.asFunction< + ffi.Pointer Function( + ffi.Pointer, int, int, int, int, int, int)>(); + /// @brief Encode a string into a barcode /// @param contents The string to encode /// @param width The width of the barcode @@ -78,7 +120,7 @@ class GeneratedBindings { /// @param logEnabled Log enabled. /// @param eccLevel The error correction level of the barcode. Used for Aztec, PDF417, and QRCode only, [0-8]. /// @return The barcode data - EncodeResult zxingEncode( + EncodeResult encodeBarcode( ffi.Pointer contents, int width, int height, @@ -87,7 +129,7 @@ class GeneratedBindings { int eccLevel, int logEnabled, ) { - return _zxingEncode( + return _encodeBarcode( contents, width, height, @@ -98,11 +140,11 @@ class GeneratedBindings { ); } - late final _zxingEncodePtr = _lookup< + late final _encodeBarcodePtr = _lookup< ffi.NativeFunction< EncodeResult Function(ffi.Pointer, ffi.Int32, ffi.Int32, - ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('zxingEncode'); - late final _zxingEncode = _zxingEncodePtr.asFunction< + ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('encodeBarcode'); + late final _encodeBarcode = _encodeBarcodePtr.asFunction< EncodeResult Function( ffi.Pointer, int, int, int, int, int, int)>(); } diff --git a/lib/isolate_utils.dart b/lib/isolate_utils.dart index 6b18313..c0c510f 100644 --- a/lib/isolate_utils.dart +++ b/lib/isolate_utils.dart @@ -63,7 +63,7 @@ class IsolateUtils { final cropSize = (min(image.width, image.height) * cropPercent).round(); - final result = FlutterZxing.zxingRead(bytes, isolateData.format, + final result = FlutterZxing.readBarcode(bytes, isolateData.format, image.width, image.height, cropSize, cropSize); isolateData.responsePort?.send(result); diff --git a/lib/zxing_reader_widget.dart b/lib/zxing_reader_widget.dart index 209f9c4..b9eda9d 100644 --- a/lib/zxing_reader_widget.dart +++ b/lib/zxing_reader_widget.dart @@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_beep/flutter_beep.dart'; import 'flutter_zxing.dart'; -import 'generated_bindings.dart'; import 'isolate_utils.dart'; import 'scanner_overlay.dart'; diff --git a/lib/zxing_writer_widget.dart b/lib/zxing_writer_widget.dart index 1523bb7..991b5fa 100644 --- a/lib/zxing_writer_widget.dart +++ b/lib/zxing_writer_widget.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:image/image.dart' as imglib; import 'flutter_zxing.dart'; -import 'generated_bindings.dart'; class ZxingWriterWidget extends StatefulWidget { const ZxingWriterWidget({ @@ -71,7 +70,7 @@ class _ZxingWriterWidgetState extends State decoration: InputDecoration( border: const OutlineInputBorder(), filled: true, - hintText: 'Enter text to encode', + hintText: 'Enter text to create a barcode', counterText: '${_textController.value.text.length} / $_maxTextLength', ), @@ -85,7 +84,7 @@ class _ZxingWriterWidgetState extends State final text = _textController.value.text; const width = 300; const height = 300; - final result = FlutterZxing.zxingEncode( + final result = FlutterZxing.encodeBarcode( text, width, height, _codeFormat, 5, 0); String? error; if (result.isValidBool) { @@ -107,7 +106,7 @@ class _ZxingWriterWidgetState extends State } } }, - child: const Text('Encode'), + child: const Text('Create'), ), const SizedBox(height: 20), ], diff --git a/pubspec.yaml b/pubspec.yaml index 2ef4050..623f7e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,7 +8,7 @@ environment: flutter: ">=2.5.0" dependencies: - camera: 0.9.4+19 + camera: ^0.9.4 ffi: ^1.1.2 flutter: sdk: flutter