Browse Source

added tryHarder and tryRotate attributes

pull/9/head
Khoren Markosyan 2 years ago
parent
commit
f6e4e19a56
  1. 12
      ios/Classes/src/native_zxing.cpp
  2. 98
      ios/Classes/src/native_zxing.h
  3. 79
      lib/generated_bindings.dart
  4. 11
      lib/src/logic/barcode_encoder.dart
  5. 16
      lib/src/logic/barcode_reader.dart
  6. 24
      lib/src/logic/barcodes_reader.dart
  7. 4
      pubspec.yaml

12
ios/Classes/src/native_zxing.cpp

@ -14,9 +14,9 @@ using namespace ZXing;
extern "C"
{
FUNCTION_ATTRIBUTE
void setLogEnabled(int enabled)
void setLogEnabled(int enable)
{
setLoggingEnabled(enabled);
setLoggingEnabled(enable);
}
FUNCTION_ATTRIBUTE
@ -26,7 +26,7 @@ extern "C"
}
FUNCTION_ATTRIBUTE
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight)
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate)
{
long long start = get_now();
@ -39,7 +39,7 @@ extern "C"
{
image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight);
}
DecodeHints hints = DecodeHints().setTryHarder(false).setTryRotate(true).setFormats(BarcodeFormat(format));
DecodeHints hints = DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(BarcodeFormat(format));
Result result = ReadBarcode(image, hints);
struct CodeResult code = {false, nullptr};
@ -54,7 +54,7 @@ extern "C"
}
FUNCTION_ATTRIBUTE
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight)
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate)
{
long long start = get_now();
@ -67,7 +67,7 @@ extern "C"
{
image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight);
}
DecodeHints hints = DecodeHints().setTryHarder(false).setTryRotate(true).setFormats(BarcodeFormat(format));
DecodeHints hints = DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(BarcodeFormat(format));
Results results = ReadBarcodes(image, hints);
auto *codes = new struct CodeResult[results.size()];

98
ios/Classes/src/native_zxing.h

@ -3,6 +3,10 @@ extern "C"
{
#endif
/**
* @brief Format Enumerates barcode formats known to this package.
*
*/
enum Format
{
None = 0, ///< Used as a return value if no valid barcode has been detected
@ -28,48 +32,63 @@ extern "C"
Any = OneDCodes | TwoDCodes,
};
/**
* @brief Pos is a position of a barcode in a image.
*
*/
struct Pos
{
int topLeftX;
int topLeftY;
int topRightX;
int topRightY;
int bottomLeftX;
int bottomLeftY;
int bottomRightX;
int bottomRightY;
int topLeftX; ///< x coordinate of top left corner of barcode
int topLeftY; ///< y coordinate of top left corner of barcode
int topRightX; ///< x coordinate of top right corner of barcode
int topRightY; ///< y coordinate of top right corner of barcode
int bottomLeftX; ///< x coordinate of bottom left corner of barcode
int bottomLeftY; ///< y coordinate of bottom left corner of barcode
int bottomRightX; ///< x coordinate of bottom right corner of barcode
int bottomRightY; ///< y coordinate of bottom right corner of barcode
};
/**
* @brief The CodeResult class encapsulates the result of decoding a barcode within an image.
*/
struct CodeResult
{
int isValid;
char *text;
enum Format format;
struct Pos *pos;
int isValid; ///< Whether the barcode was successfully decoded
char *text; ///< The decoded text
enum Format format; ///< The format of the barcode
struct Pos *pos; ///< The position of the barcode within the image
};
/**
* @brief The CodeResults class encapsulates the result of decoding multiple barcodes within an image.
*/
struct CodeResults
{
int count;
struct CodeResult *results;
int count; ///< The number of barcodes detected
struct CodeResult *results; ///< The results of the barcode decoding
};
/**
* @brief EncodeResult encapsulates the result of encoding a barcode.
*
*/
struct EncodeResult
{
int isValid;
char *text;
enum Format format;
const unsigned int *data;
int length;
char *error;
int isValid; ///< Whether the barcode was successfully encoded
char *text; ///< The encoded text
enum Format format; ///< The format of the barcode
const unsigned int *data; ///< The encoded data
int length; ///< The length of the encoded data
char *error; ///< The error message
};
/**
* @brief Enables or disables the logging of the library.
* @param enable Whether to enable or disable the logging.
*
* @param enabled
*/
void setLogEnabled(int enabled);
void setLogEnabled(int enable);
/**
* Returns the version of the zxing-cpp library.
@ -79,44 +98,47 @@ extern "C"
char const *version();
/**
* @brief Reads barcode from image.
* @brief Read barcode from image bytes.
* @param bytes Image bytes.
* @param format The format of the barcode
* @param width Image width.
* @param height Image height.
* @param format Specify a set of BarcodeFormats that should be searched for.
* @param width Image width in pixels.
* @param height Image height in pixels.
* @param cropWidth Crop width.
* @param cropHeight Crop height.
* @param logEnabled Log enabled.
* @return Barcode result.
* @param tryHarder Spend more time to try to find a barcode; optimize for accuracy, not speed.
* @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images.
* @return The barcode result.
*/
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight);
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate);
/**
* @brief Reads barcodes from image.
* @brief Read barcodes from image bytes.
* @param bytes Image bytes.
* @param format The format of the barcode
* @param width Image width.
* @param height Image height.
* @param format Specify a set of BarcodeFormats that should be searched for.
* @param width Image width in pixels.
* @param height Image height in pixels.
* @param cropWidth Crop width.
* @param cropHeight Crop height.
* @param logEnabled Log enabled.
* @return Barcode results.
* @param tryHarder Spend more time to try to find a barcode, optimize for accuracy, not speed.
* @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images.
* @return The barcode results.
*/
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight);
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate);
/**
* @brief Encode a string into a barcode
* @param contents The string to encode
* @param width The width of the barcode
* @param height The height of the barcode
* @param width The width of the barcode in pixels.
* @param height The height of the barcode in pixels.
* @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 encodeBarcode(char *contents, int width, int height, int format, int margin, int eccLevel);
// Private functions
void resultToCodeResult(struct CodeResult *code, ZXing::Result result);
#ifdef __cplusplus

79
lib/generated_bindings.dart

@ -20,13 +20,14 @@ class GeneratedBindings {
: _lookup = lookup;
/// @brief Enables or disables the logging of the library.
/// @param enable Whether to enable or disable the logging.
///
/// @param enabled
void setLogEnabled(
int enabled,
int enable,
) {
return _setLogEnabled(
enabled,
enable,
);
}
@ -47,15 +48,16 @@ class GeneratedBindings {
late final _version =
_versionPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
/// @brief Reads barcode from image.
/// @brief Read barcode from image bytes.
/// @param bytes Image bytes.
/// @param format The format of the barcode
/// @param width Image width.
/// @param height Image height.
/// @param format Specify a set of BarcodeFormats that should be searched for.
/// @param width Image width in pixels.
/// @param height Image height in pixels.
/// @param cropWidth Crop width.
/// @param cropHeight Crop height.
/// @param logEnabled Log enabled.
/// @return Barcode result.
/// @param tryHarder Spend more time to try to find a barcode; optimize for accuracy, not speed.
/// @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images.
/// @return The barcode result.
CodeResult readBarcode(
ffi.Pointer<ffi.Char> bytes,
int format,
@ -63,6 +65,8 @@ class GeneratedBindings {
int height,
int cropWidth,
int cropHeight,
int tryHarder,
int tryRotate,
) {
return _readBarcode(
bytes,
@ -71,25 +75,29 @@ class GeneratedBindings {
height,
cropWidth,
cropHeight,
tryHarder,
tryRotate,
);
}
late final _readBarcodePtr = _lookup<
ffi.NativeFunction<
CodeResult Function(ffi.Pointer<ffi.Char>, ffi.Int, ffi.Int, ffi.Int,
ffi.Int, ffi.Int)>>('readBarcode');
ffi.Int, ffi.Int, ffi.Int, ffi.Int)>>('readBarcode');
late final _readBarcode = _readBarcodePtr.asFunction<
CodeResult Function(ffi.Pointer<ffi.Char>, int, int, int, int, int)>();
CodeResult Function(
ffi.Pointer<ffi.Char>, int, int, int, int, int, int, int)>();
/// @brief Reads barcodes from image.
/// @brief Read barcodes from image bytes.
/// @param bytes Image bytes.
/// @param format The format of the barcode
/// @param width Image width.
/// @param height Image height.
/// @param format Specify a set of BarcodeFormats that should be searched for.
/// @param width Image width in pixels.
/// @param height Image height in pixels.
/// @param cropWidth Crop width.
/// @param cropHeight Crop height.
/// @param logEnabled Log enabled.
/// @return Barcode results.
/// @param tryHarder Spend more time to try to find a barcode, optimize for accuracy, not speed.
/// @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images.
/// @return The barcode results.
CodeResults readBarcodes(
ffi.Pointer<ffi.Char> bytes,
int format,
@ -97,6 +105,8 @@ class GeneratedBindings {
int height,
int cropWidth,
int cropHeight,
int tryHarder,
int tryRotate,
) {
return _readBarcodes(
bytes,
@ -105,23 +115,25 @@ class GeneratedBindings {
height,
cropWidth,
cropHeight,
tryHarder,
tryRotate,
);
}
late final _readBarcodesPtr = _lookup<
ffi.NativeFunction<
CodeResults Function(ffi.Pointer<ffi.Char>, ffi.Int, ffi.Int, ffi.Int,
ffi.Int, ffi.Int)>>('readBarcodes');
ffi.Int, ffi.Int, ffi.Int, ffi.Int)>>('readBarcodes');
late final _readBarcodes = _readBarcodesPtr.asFunction<
CodeResults Function(ffi.Pointer<ffi.Char>, int, int, int, int, int)>();
CodeResults Function(
ffi.Pointer<ffi.Char>, int, 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
/// @param height The height of the barcode
/// @param width The width of the barcode in pixels.
/// @param height The height of the barcode in pixels.
/// @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 encodeBarcode(
@ -150,6 +162,7 @@ class GeneratedBindings {
EncodeResult Function(ffi.Pointer<ffi.Char>, int, int, int, int, int)>();
}
/// @brief Format Enumerates barcode formats known to this package.
abstract class Format {
/// < Used as a return value if no valid barcode has been detected
static const int None = 0;
@ -206,64 +219,88 @@ abstract class Format {
static const int Any = 65535;
}
/// @brief Pos is a position of a barcode in a image.
class Pos extends ffi.Struct {
/// < x coordinate of top left corner of barcode
@ffi.Int()
external int topLeftX;
/// < y coordinate of top left corner of barcode
@ffi.Int()
external int topLeftY;
/// < x coordinate of top right corner of barcode
@ffi.Int()
external int topRightX;
/// < y coordinate of top right corner of barcode
@ffi.Int()
external int topRightY;
/// < x coordinate of bottom left corner of barcode
@ffi.Int()
external int bottomLeftX;
/// < y coordinate of bottom left corner of barcode
@ffi.Int()
external int bottomLeftY;
/// < x coordinate of bottom right corner of barcode
@ffi.Int()
external int bottomRightX;
/// < y coordinate of bottom right corner of barcode
@ffi.Int()
external int bottomRightY;
}
/// @brief The CodeResult class encapsulates the result of decoding a barcode within an image.
class CodeResult extends ffi.Struct {
/// < Whether the barcode was successfully decoded
@ffi.Int()
external int isValid;
/// < The decoded text
external ffi.Pointer<ffi.Char> text;
/// < The format of the barcode
@ffi.Int32()
external int format;
/// < The position of the barcode within the image
external ffi.Pointer<Pos> pos;
}
/// @brief The CodeResults class encapsulates the result of decoding multiple barcodes within an image.
class CodeResults extends ffi.Struct {
/// < The number of barcodes detected
@ffi.Int()
external int count;
/// < The results of the barcode decoding
external ffi.Pointer<CodeResult> results;
}
/// @brief EncodeResult encapsulates the result of encoding a barcode.
class EncodeResult extends ffi.Struct {
/// < Whether the barcode was successfully encoded
@ffi.Int()
external int isValid;
/// < The encoded text
external ffi.Pointer<ffi.Char> text;
/// < The format of the barcode
@ffi.Int32()
external int format;
/// < The encoded data
external ffi.Pointer<ffi.UnsignedInt> data;
/// < The length of the encoded data
@ffi.Int()
external int length;
/// < The error message
external ffi.Pointer<ffi.Char> error;
}

11
lib/src/logic/barcode_encoder.dart

@ -1,7 +1,14 @@
part of 'zxing.dart';
EncodeResult encodeBarcode(String contents, int width, int height, int format,
int margin, int eccLevel) {
// Encode a string into a barcode
EncodeResult encodeBarcode(
String contents,
int width,
int height,
int format,
int margin,
int eccLevel,
) {
return bindings.encodeBarcode(
contents.toNativeUtf8().cast<Char>(),
width,

16
lib/src/logic/barcode_reader.dart

@ -6,12 +6,16 @@ Future<CodeResult?> readBarcodeImagePathString(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) =>
readBarcodeImagePath(
XFile(path),
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
/// Reads barcode from XFile image path
@ -20,6 +24,8 @@ Future<CodeResult?> readBarcodeImagePath(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) async {
final Uint8List imageBytes = await path.readAsBytes();
final imglib.Image? image = imglib.decodeImage(imageBytes);
@ -33,6 +39,8 @@ Future<CodeResult?> readBarcodeImagePath(
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
}
@ -42,6 +50,8 @@ Future<CodeResult?> readBarcodeImageUrl(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) async {
final Uint8List imageBytes =
(await NetworkAssetBundle(Uri.parse(url)).load(url)).buffer.asUint8List();
@ -56,6 +66,8 @@ Future<CodeResult?> readBarcodeImageUrl(
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
}
@ -67,6 +79,8 @@ CodeResult readBarcode(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) =>
bindings.readBarcode(
bytes.allocatePointer(),
@ -75,4 +89,6 @@ CodeResult readBarcode(
height,
cropWidth,
cropHeight,
tryHarder ? 1 : 0,
tryRotate ? 1 : 0,
);

24
lib/src/logic/barcodes_reader.dart

@ -6,12 +6,16 @@ Future<List<CodeResult>> readBarcodesImagePathString(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) =>
readBarcodesImagePath(
XFile(path),
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
/// Reads barcodes from XFile image path
@ -20,6 +24,8 @@ Future<List<CodeResult>> readBarcodesImagePath(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) async {
final Uint8List imageBytes = await path.readAsBytes();
final imglib.Image? image = imglib.decodeImage(imageBytes);
@ -33,6 +39,8 @@ Future<List<CodeResult>> readBarcodesImagePath(
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
}
@ -42,6 +50,8 @@ Future<List<CodeResult>> readBarcodesImageUrl(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) async {
final Uint8List imageBytes =
(await NetworkAssetBundle(Uri.parse(url)).load(url)).buffer.asUint8List();
@ -56,6 +66,8 @@ Future<List<CodeResult>> readBarcodesImageUrl(
format: format,
cropWidth: cropWidth,
cropHeight: cropHeight,
tryHarder: tryHarder,
tryRotate: tryRotate,
);
}
@ -67,9 +79,19 @@ List<CodeResult> readBarcodes(
int format = Format.Any,
int cropWidth = 0,
int cropHeight = 0,
bool tryHarder = false,
bool tryRotate = true,
}) {
final CodeResults result = bindings.readBarcodes(
bytes.allocatePointer(), format, width, height, cropWidth, cropHeight);
bytes.allocatePointer(),
format,
width,
height,
cropWidth,
cropHeight,
tryHarder ? 1 : 0,
tryRotate ? 1 : 0,
);
final List<CodeResult> results = <CodeResult>[];
for (int i = 0; i < result.count; i++) {
results.add(result.results.elementAt(i).ref);

4
pubspec.yaml

@ -36,5 +36,9 @@ ffigen:
headers:
entry-points:
- "ios/Classes/src/native_zxing.h"
functions:
exclude:
- resultToCodeResult
# flutter pub publish --dry-run
Loading…
Cancel
Save