Browse Source

allow to read barcode from image

pull/3/head
Khoren Markosyan 3 years ago
parent
commit
d0fc094106
  1. 35
      example/ios/Podfile.lock
  2. 112
      example/lib/pages/creator_page.dart
  3. 141
      example/lib/pages/history_page.dart
  4. 80
      example/lib/pages/scanner_page.dart
  5. 44
      example/pubspec.lock
  6. 1
      example/pubspec.yaml
  7. 49
      ios/Classes/src/native_zxing.cpp
  8. 19
      ios/Classes/src/native_zxing.h
  9. 28
      lib/flutter_zxing.dart
  10. 76
      lib/generated_bindings.dart
  11. 2
      lib/isolate_utils.dart
  12. 1
      lib/zxing_reader_widget.dart
  13. 7
      lib/zxing_writer_widget.dart
  14. 2
      pubspec.yaml

35
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

112
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<CreatorPage> createState() => _CreatorPageState();
}
class _CreatorPageState extends State<CreatorPage>
with TickerProviderStateMixin {
CameraController? controller;
TabController? _tabController;
class _CreatorPageState extends State<CreatorPage> {
bool isAndroid() => Theme.of(context).platform == TargetPlatform.android;
// Scan result queue
final _resultQueue = <CodeResult>[];
// Write result
Uint8List? writeResult;
// true when the camera is active
bool _isScanning = true;
@override
void initState() {
super.initState();
@ -47,64 +32,18 @@ class _CreatorPageState extends State<CreatorPage>
}
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(
body: SingleChildScrollView(
child: Column(
children: [
ZxingWriterWidget(
@ -120,11 +59,14 @@ class _CreatorPageState extends State<CreatorPage>
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
content: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: Text(
error,
textAlign: TextAlign.center,
),
),
),
);
},
),
@ -132,8 +74,6 @@ class _CreatorPageState extends State<CreatorPage>
],
),
),
],
),
);
}
@ -157,44 +97,4 @@ class _CreatorPageState extends State<CreatorPage>
],
);
}
_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(() {});
},
),
],
),
);
},
);
}
}

141
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<HistoryPage> createState() => _HistoryPageState();
}
class _HistoryPageState extends State<HistoryPage> with TickerProviderStateMixin {
CameraController? controller;
TabController? _tabController;
bool isAndroid() => Theme.of(context).platform == TargetPlatform.android;
// Scan result queue
class _HistoryPageState extends State<HistoryPage> {
final _resultQueue = <CodeResult>[];
// 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<HistoryPage> 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,

80
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<ScannerPage> createState() => _ScannerPageState();
}
class _ScannerPageState extends State<ScannerPage>
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<ScannerPage> {
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 {
body: 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(),
],
},
),
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);
}
}
}
},
),
);
}

44
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:

1
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

49
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<int>(result.format()));
codes[i] = code;
i++;
}
}
int evalInMillis = static_cast<int>(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();

19
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
}

28
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<Utf8>().toDartString();
static String version() {
return bindings.version().cast<Utf8>().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<CodeResult> 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<Int8>(),
var result = bindings.encodeBarcode(contents.toNativeUtf8().cast<Int8>(),
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<Utf8>().toDartString();
String? get textString =>
text == nullptr ? null : text.cast<Utf8>().toDartString();
String get formatString {
return CodeFormat.formatName(format);

76
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<ffi.Int8> zxingVersion() {
return _zxingVersion();
ffi.Pointer<ffi.Int8> version() {
return _version();
}
late final _zxingVersionPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Int8> Function()>>(
'zxingVersion');
late final _zxingVersion =
_zxingVersionPtr.asFunction<ffi.Pointer<ffi.Int8> Function()>();
late final _versionPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Int8> Function()>>('version');
late final _version =
_versionPtr.asFunction<ffi.Pointer<ffi.Int8> 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<ffi.Int8> 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.Int8>, 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<ffi.Int8>, 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<CodeResult> readBarcodes(
ffi.Pointer<ffi.Int8> 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<CodeResult> Function(
ffi.Pointer<ffi.Int8>,
ffi.Int32,
ffi.Int32,
ffi.Int32,
ffi.Int32,
ffi.Int32,
ffi.Int32)>>('readBarcodes');
late final _readBarcodes = _readBarcodesPtr.asFunction<
ffi.Pointer<CodeResult> Function(
ffi.Pointer<ffi.Int8>, 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<ffi.Int8> 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.Int8>, 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<ffi.Int8>, int, int, int, int, int, int)>();
}

2
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);

1
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';

7
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<ZxingWriterWidget>
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<ZxingWriterWidget>
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<ZxingWriterWidget>
}
}
},
child: const Text('Encode'),
child: const Text('Create'),
),
const SizedBox(height: 20),
],

2
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

Loading…
Cancel
Save