Browse Source

allow to set code format for reader

pull/3/head
Khoren Markosyan 3 years ago
parent
commit
8425459c6a
  1. 10
      example/pubspec.lock
  2. 2
      example/pubspec.yaml
  3. 30
      ios/Classes/src/native_zxing.cpp
  4. 10
      ios/Classes/src/native_zxing.h
  5. 13
      lib/flutter_zxing.dart
  6. 30
      lib/generated_bindings.dart
  7. 25
      lib/isolate_utils.dart
  8. 5
      lib/zxing_reader_widget.dart
  9. 2
      pubspec.yaml

10
example/pubspec.lock

@ -7,7 +7,7 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.2"
version: "3.3.0"
async:
dependency: transitive
description:
@ -28,7 +28,7 @@ packages:
name: camera
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.4+16"
version: "0.9.4+19"
camera_platform_interface:
dependency: transitive
description:
@ -302,7 +302,7 @@ packages:
name: share_plus
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
version: "4.0.3"
share_plus_linux:
dependency: transitive
description:
@ -323,7 +323,7 @@ packages:
name: share_plus_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.2"
share_plus_web:
dependency: transitive
description:
@ -468,7 +468,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.2"
version: "2.5.1"
xdg_directories:
dependency: transitive
description:

2
example/pubspec.yaml

@ -13,7 +13,7 @@ dependencies:
flutter_zxing:
path: ../
path_provider: ^2.0.9
share_plus: ^4.0.1
share_plus: ^4.0.3
dev_dependencies:
flutter_lints: ^1.0.0

30
ios/Classes/src/native_zxing.cpp

@ -16,7 +16,7 @@ extern "C"
}
FUNCTION_ATTRIBUTE
struct CodeResult zxingRead(char *bytes, int width, int height, int cropSize)
struct CodeResult zxingRead(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled)
{
long long start = get_now();
@ -24,11 +24,12 @@ extern "C"
uint8_t *data = new uint8_t[length];
memcpy(data, bytes, length);
BarcodeFormats formats = BarcodeFormat::Any;
BarcodeFormats formats = BarcodeFormat(format); // BarcodeFormat::Any;
DecodeHints hints = DecodeHints().setTryHarder(false).setTryRotate(true).setFormats(formats);
ImageView image{data, width, height, ImageFormat::Lum};
if (cropSize > 0 && cropSize < width && cropSize < height) {
image = image.cropped(width / 2 - cropSize / 2, height / 2 - cropSize / 2, cropSize, cropSize);
if (cropWidth > 0 && cropHeight > 0 && cropWidth < width && cropHeight < height)
{
image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight);
}
Result result = ReadBarcode(image, hints);
@ -43,16 +44,19 @@ extern "C"
}
int evalInMillis = static_cast<int>(get_now() - start);
platform_log("Read done in %dms\n", evalInMillis);
if (logEnabled)
{
platform_log("zxingRead: %d ms", evalInMillis);
}
return code;
}
FUNCTION_ATTRIBUTE
struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel)
struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled)
{
long long start = get_now();
struct EncodeResult result = { nullptr, 0, false, nullptr };
struct EncodeResult result = {nullptr, 0, false, nullptr};
try
{
auto writer = MultiFormatWriter(BarcodeFormat(format)).setMargin(margin).setEccLevel(eccLevel);
@ -63,13 +67,19 @@ extern "C"
}
catch (const std::exception &e)
{
platform_log("Can't encode text: %s\nError: %s\n", contents, e.what());
if (logEnabled)
{
platform_log("Can't encode text: %s\nError: %s\n", contents, e.what());
}
result.error = new char[strlen(e.what()) + 1];
strcpy(result.error, e.what());
}
int evalInMillis = static_cast<int>(get_now() - start);
platform_log("Encode done in %dms\n", evalInMillis);
if (logEnabled)
{
platform_log("zxingEncode: %d ms", evalInMillis);
}
return result;
}
}

10
ios/Classes/src/native_zxing.h

@ -53,12 +53,15 @@ extern "C"
/**
* @brief Reads barcode from image.
* @param bytes Image bytes.
* @param format The format of the barcode
* @param width Image width.
* @param height Image height.
* @param cropSize Crop size.
* @param cropWidth Crop width.
* @param cropHeight Crop height.
* @param logEnabled Log enabled.
* @return Barcode result.
*/
struct CodeResult zxingRead(char *bytes, int width, int height, int cropSize);
struct CodeResult zxingRead(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int logEnabled);
/**
* @brief Encode a string into a barcode
@ -67,10 +70,11 @@ extern "C"
* @param height The height of the barcode
* @param format The format of the barcode
* @param margin The margin of the barcode
* @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
*/
struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel);
struct EncodeResult zxingEncode(char *contents, int width, int height, int format, int margin, int eccLevel, int logEnabled);
#ifdef __cplusplus
}

13
lib/flutter_zxing.dart

@ -18,21 +18,26 @@ class FlutterZxing {
static final bindings = GeneratedBindings(dylib);
static bool logEnabled = true;
static String zxingVersion() {
return bindings.zxingVersion().cast<Utf8>().toDartString();
}
static CodeResult zxingRead(
Uint8List bytes, int width, int height, int cropSize) {
return bindings.zxingRead(bytes.allocatePointer(), width, height, cropSize);
static CodeResult zxingRead(Uint8List bytes, int format, int width,
int height, int cropWidth, int cropHeight) {
return bindings.zxingRead(bytes.allocatePointer(), format, width, height,
cropWidth, cropHeight, _logEnabled);
}
static EncodeResult zxingEncode(String contents, int width, int height,
int format, int margin, int eccLevel) {
var result = bindings.zxingEncode(contents.toNativeUtf8().cast<Int8>(),
width, height, format, margin, eccLevel);
width, height, format, margin, eccLevel, _logEnabled);
return result;
}
static int get _logEnabled => logEnabled ? 1 : 0;
}
// Getting a library that holds needed symbols

30
lib/generated_bindings.dart

@ -34,30 +34,40 @@ class GeneratedBindings {
/// @brief Reads barcode from image.
/// @param bytes Image bytes.
/// @param format The format of the barcode
/// @param width Image width.
/// @param height Image height.
/// @param cropSize Crop size.
/// @param cropWidth Crop width.
/// @param cropHeight Crop height.
/// @param logEnabled Log enabled.
/// @return Barcode result.
CodeResult zxingRead(
ffi.Pointer<ffi.Int8> bytes,
int format,
int width,
int height,
int cropSize,
int cropWidth,
int cropHeight,
int logEnabled,
) {
return _zxingRead(
bytes,
format,
width,
height,
cropSize,
cropWidth,
cropHeight,
logEnabled,
);
}
late final _zxingReadPtr = _lookup<
ffi.NativeFunction<
CodeResult Function(ffi.Pointer<ffi.Int8>, ffi.Int32, ffi.Int32,
ffi.Int32)>>('zxingRead');
late final _zxingRead = _zxingReadPtr
.asFunction<CodeResult Function(ffi.Pointer<ffi.Int8>, int, int, int)>();
ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('zxingRead');
late final _zxingRead = _zxingReadPtr.asFunction<
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
@ -65,6 +75,7 @@ class GeneratedBindings {
/// @param height The height of the barcode
/// @param format The format of the barcode
/// @param margin The margin of the barcode
/// @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(
@ -74,6 +85,7 @@ class GeneratedBindings {
int format,
int margin,
int eccLevel,
int logEnabled,
) {
return _zxingEncode(
contents,
@ -82,15 +94,17 @@ class GeneratedBindings {
format,
margin,
eccLevel,
logEnabled,
);
}
late final _zxingEncodePtr = _lookup<
ffi.NativeFunction<
EncodeResult Function(ffi.Pointer<ffi.Int8>, ffi.Int32, ffi.Int32,
ffi.Int32, ffi.Int32, ffi.Int32)>>('zxingEncode');
ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32)>>('zxingEncode');
late final _zxingEncode = _zxingEncodePtr.asFunction<
EncodeResult Function(ffi.Pointer<ffi.Int8>, int, int, int, int, int)>();
EncodeResult Function(
ffi.Pointer<ffi.Int8>, int, int, int, int, int, int)>();
}
abstract class Format {

25
lib/isolate_utils.dart

@ -11,12 +11,14 @@ import 'image_converter.dart';
/// Bundles data to pass between Isolate
class IsolateData {
CameraImage cameraImage;
int format;
double cropPercent;
SendPort? responsePort;
IsolateData(
this.cameraImage,
this.format,
this.cropPercent,
);
}
@ -54,15 +56,20 @@ class IsolateUtils {
await for (final IsolateData? isolateData in port) {
if (isolateData != null) {
final image = isolateData.cameraImage;
final cropPercent = isolateData.cropPercent;
final bytes = await convertImage(image);
final cropSize = (min(image.width, image.height) * cropPercent).round();
final result =
FlutterZxing.zxingRead(bytes, image.width, image.height, cropSize);
isolateData.responsePort?.send(result);
try {
final image = isolateData.cameraImage;
final cropPercent = isolateData.cropPercent;
final bytes = await convertImage(image);
final cropSize =
(min(image.width, image.height) * cropPercent).round();
final result = FlutterZxing.zxingRead(bytes, isolateData.format,
image.width, image.height, cropSize, cropSize);
isolateData.responsePort?.send(result);
} on Exception catch (e) {
isolateData.responsePort?.send(e);
}
}
}
}

5
lib/zxing_reader_widget.dart

@ -18,6 +18,7 @@ class ZxingReaderWidget extends StatefulWidget {
Key? key,
required this.onScan,
this.onControllerCreated,
this.codeFormat = Format.Any,
this.beep = true,
this.showCroppingRect = true,
this.scanDelay = const Duration(milliseconds: 500), // 500ms delay
@ -27,6 +28,7 @@ class ZxingReaderWidget extends StatefulWidget {
final Function(CodeResult) onScan;
final Function(CameraController?)? onControllerCreated;
final int codeFormat;
final bool beep;
final bool showCroppingRect;
final Duration scanDelay;
@ -144,7 +146,8 @@ class _ZxingReaderWidgetState extends State<ZxingReaderWidget>
if (!_isProcessing) {
_isProcessing = true;
try {
var isolateData = IsolateData(image, widget.cropPercent);
var isolateData =
IsolateData(image, widget.codeFormat, widget.cropPercent);
/// perform inference in separate isolate
CodeResult result = await inference(isolateData);

2
pubspec.yaml

@ -8,7 +8,7 @@ environment:
flutter: ">=2.5.0"
dependencies:
camera: ^0.9.4+16
camera: ^0.9.4
ffi: ^1.1.2
flutter:
sdk: flutter

Loading…
Cancel
Save