diff --git a/example/pubspec.lock b/example/pubspec.lock index 8f91a5e..1cc25db 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -28,14 +28,14 @@ packages: name: camera url: "https://pub.dartlang.org" source: hosted - version: "0.9.7" + version: "0.9.7+1" camera_platform_interface: dependency: transitive description: name: camera_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "2.2.0" camera_web: dependency: transitive description: @@ -141,7 +141,7 @@ packages: path: ".." relative: true source: path - version: "0.1.2" + version: "0.1.3" font_awesome_flutter: dependency: "direct main" description: @@ -183,7 +183,7 @@ packages: name: image_picker_android url: "https://pub.dartlang.org" source: hosted - version: "0.8.4+13" + version: "0.8.5" image_picker_for_web: dependency: transitive description: diff --git a/lib/flutter_zxing.dart b/lib/flutter_zxing.dart index cdec67c..850e5b1 100644 --- a/lib/flutter_zxing.dart +++ b/lib/flutter_zxing.dart @@ -3,9 +3,11 @@ import 'dart:ffi'; import 'dart:io'; import 'dart:typed_data'; +import 'package:camera/camera.dart'; import 'package:ffi/ffi.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:image/image.dart' as imglib; import 'generated_bindings.dart'; @@ -31,8 +33,64 @@ class FlutterZxing { logEnabled = enabled; } - static String version() { - return bindings.version().cast().toDartString(); + /// Returns a version of the zxing library + static String version() => bindings.version().cast().toDartString(); + + /// Reads barcode from String image path + static Future readImagePathString( + String path, { + int format = Format.Any, + int cropWidth = 0, + int cropHeight = 0, + }) => + readImagePath(XFile(path), + format: format, cropWidth: cropWidth, cropHeight: cropHeight); + + /// Reads barcode from XFile image path + static Future readImagePath( + XFile path, { + int format = Format.Any, + int cropWidth = 0, + int cropHeight = 0, + }) async { + final Uint8List imageBytes = await path.readAsBytes(); + imglib.Image? image = imglib.decodeImage(imageBytes); + if (image == null) { + return null; + } + return readBarcode( + image.getBytes(format: imglib.Format.luminance), + format, + image.width, + image.height, + cropWidth, + cropHeight, + ); + } + + /// Reads barcode from image url + static Future readImageUrl( + String url, { + int format = Format.Any, + int cropWidth = 0, + int cropHeight = 0, + }) async { + final Uint8List imageBytes = + (await NetworkAssetBundle(Uri.parse(url)).load(url)) + .buffer + .asUint8List(); + imglib.Image? image = imglib.decodeImage(imageBytes); + if (image == null) { + return null; + } + return readBarcode( + image.getBytes(format: imglib.Format.luminance), + format, + image.width, + image.height, + cropWidth, + cropHeight, + ); } static CodeResult readBarcode(Uint8List bytes, int format, int width, diff --git a/pubspec.yaml b/pubspec.yaml index 076a6de..074816d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: image: ^3.2.0 dev_dependencies: - ffigen: ^5.0.0 # dart run ffigen + ffigen: ^6.0.0 # dart run ffigen flutter_lints: ^2.0.1 flutter_test: sdk: flutter diff --git a/zxscanner/lib/pages/help_page.dart b/zxscanner/lib/pages/help_page.dart index 4ed0d85..6d8516c 100644 --- a/zxscanner/lib/pages/help_page.dart +++ b/zxscanner/lib/pages/help_page.dart @@ -1,10 +1,5 @@ -import 'dart:typed_data'; - import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:flutter_zxing/flutter_zxing.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:image/image.dart' as imglib; import 'package:url_launcher/url_launcher_string.dart'; import 'package:zxscanner/configs/constants.dart'; import 'package:zxscanner/widgets/common_widgets.dart'; @@ -52,22 +47,7 @@ class HelpPage extends StatelessWidget { BuildContext context, { String? title, String? body, - int format = Format.QRCode, - String? qrText, - int width = 100, - int height = 100, }) { - Uint8List? bytes; - if (qrText != null) { - final result = - FlutterZxing.encodeBarcode(qrText, width, height, format, 5, 0); - if (result.isValidBool) { - final img = imglib.Image.fromBytes(width, height, result.bytes); - bytes = Uint8List.fromList(imglib.encodeJpg(img)); - } else { - debugPrint('Error: ${result.errorMessage}'); - } - } return Card( margin: const EdgeInsets.all(8.0), child: Padding( @@ -77,12 +57,6 @@ class HelpPage extends StatelessWidget { dividerColor: Colors.transparent, ), child: ExpansionTile( - leading: bytes != null - ? Image.memory(bytes, width: 100) - : const SizedBox( - width: 100, - child: Icon(FontAwesomeIcons.barcode, size: 50), - ), title: Text(title ?? ''), children: [ Padding( @@ -108,8 +82,6 @@ QR codes are highly versatile and cover a range of applications because they sto * Can be used free of charge – specifications are available from the Swiss-based International Organization for Standardization. * Automatic error correction recovers damage to up to 30%, depending on the correction level chosen. """, - format: Format.QRCode, - qrText: '123456789012', ), createSlide( context, @@ -123,8 +95,6 @@ Due to its small size and large storage capacity, the Data Matrix code is most f * Often engraved on items via Direct Part Marking (DPM). * Readable even with low contrast. """, - format: Format.DataMatrix, - qrText: '123456789012', ), createSlide( context, @@ -138,8 +108,6 @@ The transportation sector accounts for most Aztec Code use cases. Lufthansa airl * Enables both high data density and up to 95% error tolerance. * Pattern resembles a top-down view of an Aztec pyramid """, - format: Format.Aztec, - qrText: '123456789012', ), createSlide( context, @@ -152,7 +120,6 @@ Ticketing, travel, and logistics are some of the most common areas of applicatio * High data density, yet with adjustable length and width. * Striking redundancy: Up to 40% damage can be compensated. """, - format: Format.PDF417, ), createSlide( context, @@ -163,9 +130,6 @@ The Universal Product Code (UPC) is perfect for retail, warehousing, and distrib * One-dimensional barcode that stores exactly 12 numeric characters, which form the Global Trade Item Number (GTIN). * The low data density makes it inadequate for encoding complex data. """, - format: Format.UPCA, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -177,9 +141,6 @@ The most important areas of application for EAN codes are retail, distribution, * The last digit is a mod10 checksum. * EAN codes are defined as GS1 standards. """, - format: Format.EAN13, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -191,9 +152,6 @@ Unlike other common barcodes, Code 39 can also encode letters, which makes it in * The low data density makes it unsuitable for tiny items. * Standardized as ANSI MH 10.8 M-1983 and ANSI/AIM BC1/1995. """, - format: Format.Code39, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -203,9 +161,6 @@ This barcode symbology can store alphanumeric characters. Its main user, Canada * One-dimensional barcode encoding 43 alphanumeric characters and 5 special characters. * In Code 93 Extended, combinations of those characters can represent all 128 ASCII characters. """, - format: Format.Code93, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -216,9 +171,6 @@ The Code 128 barcode is most frequently used in transporting goods, especially t * Can encode all ASCII characters, including special characters. * High data density compared to other 1D barcode formats. """, - format: Format.Code128, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -231,9 +183,6 @@ The Codabar barcode is only used in blood banks, libraries, and in laboratories. * Stores up to 16 characters. * Newer barcode types can store more data in less space. """, - format: Format.Codabar, - qrText: '123456789012', - width: 200, ), createSlide( context, @@ -244,9 +193,6 @@ ITF barcodes are often described as Standard Distribution Codes. They are freque * High data density, as data is stored in both the bars and the gaps.  * Compared to other linear barcodes, more data can be accommodated using the same label size. """, - format: Format.ITF, - qrText: '123456789012', - width: 200, ), ]; } diff --git a/zxscanner/lib/pages/scanner_page.dart b/zxscanner/lib/pages/scanner_page.dart index 27fe915..6472529 100644 --- a/zxscanner/lib/pages/scanner_page.dart +++ b/zxscanner/lib/pages/scanner_page.dart @@ -1,5 +1,3 @@ -import 'dart:typed_data'; - import 'package:flutter/material.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; import 'package:zxscanner/models/models.dart'; @@ -7,7 +5,6 @@ import 'package:zxscanner/utils/db_service.dart'; import 'package:zxscanner/utils/extensions.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({ @@ -52,23 +49,12 @@ class _ScannerPageState extends State { } readCodeFromImage(XFile file) async { - 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) { - addCode(result); - } else { - if (!mounted) return; - context.showToast('No code found'); - } + final CodeResult? result = await FlutterZxing.readImagePath(file); + if (result != null && result.isValidBool) { + addCode(result); + } else { + if (!mounted) return; + context.showToast('No code found'); } } diff --git a/zxscanner/pubspec.lock b/zxscanner/pubspec.lock index 0714194..4b6247c 100644 --- a/zxscanner/pubspec.lock +++ b/zxscanner/pubspec.lock @@ -70,7 +70,7 @@ packages: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.9" build_runner: dependency: "direct dev" description: @@ -105,14 +105,14 @@ packages: name: camera url: "https://pub.dartlang.org" source: hosted - version: "0.9.7" + version: "0.9.7+1" camera_platform_interface: dependency: transitive description: name: camera_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "2.2.0" camera_web: dependency: transitive description: @@ -168,7 +168,7 @@ packages: name: convert url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.0.2" convex_bottom_bar: dependency: "direct main" description: @@ -196,7 +196,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.5" dart_style: dependency: transitive description: @@ -269,7 +269,7 @@ packages: name: flutter_markdown url: "https://pub.dartlang.org" source: hosted - version: "0.6.10+1" + version: "0.6.10+2" flutter_mobx: dependency: "direct main" description: @@ -300,7 +300,7 @@ packages: path: ".." relative: true source: path - version: "0.1.2" + version: "0.1.3" font_awesome_flutter: dependency: "direct main" description: @@ -391,7 +391,7 @@ packages: name: image_picker_android url: "https://pub.dartlang.org" source: hosted - version: "0.8.4+13" + version: "0.8.5" image_picker_for_web: dependency: transitive description: @@ -545,7 +545,7 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.6" + version: "2.1.7" path_provider_macos: dependency: transitive description: @@ -566,7 +566,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "2.0.7" petitparser: dependency: transitive description: @@ -629,7 +629,7 @@ packages: name: share_plus url: "https://pub.dartlang.org" source: hosted - version: "4.0.4" + version: "4.0.6" share_plus_linux: dependency: transitive description: @@ -643,28 +643,28 @@ packages: name: share_plus_macos url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "3.0.3" share_plus_web: dependency: transitive description: name: share_plus_web url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" share_plus_windows: dependency: transitive description: name: share_plus_windows url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" shared_preferences: dependency: "direct main" description: diff --git a/zxscanner/pubspec.yaml b/zxscanner/pubspec.yaml index 24dd7b6..0be9e7c 100644 --- a/zxscanner/pubspec.yaml +++ b/zxscanner/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: convex_bottom_bar: ^3.0.0 - cupertino_icons: ^1.0.2 + cupertino_icons: ^1.0.5 flex_color_scheme: ^5.0.1 flutter: sdk: flutter @@ -27,7 +27,7 @@ dependencies: intl: ^0.17.0 mobx: ^2.0.7 path_provider: ^2.0.10 - share_plus: ^4.0.4 + share_plus: ^4.0.6 shared_preferences: ^2.0.15 url_launcher: ^6.1.2