-
-
Notifications
You must be signed in to change notification settings - Fork 464
wasm wrapper: add function to reader to scan multiple barcode #567
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wasm wrapper: add function to reader to scan multiple barcode #567
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
wrappers/wasm/BarcodeReader.cpp
Outdated
std::vector<ReadResult> results{}; | ||
std::string error{}; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the approach used here more. I mean to simply return a vector<ReadResult>
instead of a new composite data type ReadResults
. If there should be an exception, then adding a 1-element vector with the error message set, is a viable solution.
wrappers/wasm/BarcodeReader.cpp
Outdated
ReadResults readResults{}; | ||
readResults.results.reserve(results.size()); | ||
|
||
for ( auto& result : results) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not too much of a hassle, please use clang-format to format your edits.
wrappers/wasm/BarcodeReader.cpp
Outdated
@@ -57,13 +68,49 @@ ReadResult readBarcodeFromImage(int bufferPtr, int bufferLength, bool tryHarder, | |||
if (buffer == nullptr) | |||
return {"", "", "Error loading image"}; | |||
|
|||
return readBarcodeFromImageView({buffer.get(), width, height, ImageFormat::Lum}, tryHarder, format); | |||
ReadResults results = readBarcodesFromImageView({buffer.get(), width, height, ImageFormat::Lum}, tryHarder, format, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to implement readBardcodeFromImage
by calling readBardcodesFromImage
and thereby not duplicating the stbi_load_...
calls?
wrappers/wasm/demo_reader.html
Outdated
ctx.stroke(); | ||
|
||
// Example to use JavaScript Array created from an Iterator | ||
const resultArray = Array.from(new ReaderResultVectorIterator(results)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating an array with a copy of the data here, only to then iterate over it in an indexed for loop, does not make much sense to me. Please either use the .size(), .get() API or the for( ... on ...)
syntax.
wrappers/wasm/demo_reader.html
Outdated
@@ -12,6 +12,46 @@ | |||
zxing = instance; // this line is supposedly not required but with current emsdk it is :-/ | |||
}); | |||
|
|||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This iterator seems a bit over the top, just to replace a for( int ... )
with a for( ... on ... )
loop in this simple demo, but I generally like abstractions and maybe someone learns something from it for a 'real' application. Keep it or leave it, as you prefer.
Thanks for the review. I've just added commits to:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two one-line fixes remaining. Looking very good but I have not tested the code yet. I trust that you did ;).
wrappers/wasm/BarcodeReader.cpp
Outdated
{ | ||
using namespace ZXing; | ||
auto results = readBarcodesFromImage(bufferPtr, bufferLength, tryHarder, format, 1); | ||
return results.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail/throw/segfault if results
is empty. A line like return results.empty() ? ReadResult() : results.front();
should work.
wrappers/wasm/BarcodeReader.cpp
Outdated
} | ||
|
||
ReadResult readBarcodeFromPixmap(int bufferPtr, int imgWidth, int imgHeight, bool tryHarder, std::string format) | ||
{ | ||
using namespace ZXing; | ||
return readBarcodeFromImageView({reinterpret_cast<uint8_t*>(bufferPtr), imgWidth, imgHeight, ImageFormat::RGBX}, tryHarder, format); | ||
auto results = readBarcodesFromPixmap(bufferPtr, imgWidth, imgHeight, tryHarder, format, 1); | ||
return results.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
Thanks for the review, I've just fixed it. I've just tested manually with the old and new demo_reader page and images available in the test/samples/multi-1 folder :) |
Thanks a lot. I decided to squash the 6 commits into 1. |
It looks like immediately after I merged this, someone discovered an issue with the new code: #568. Could you maybe have a look at it? |
I wrote a new patch as discussed in #565 to update the wasm wrapper to allow to scan multiple barcodes with only one call.
This patch adds two new functions
readBarcodesFromPixmap
andreadBarcodesFromPixmap
. They return a new structureReadResults
. All found barcode are stored in thevector<ReadResult> results
property (theirerror
property is always empty). If an error occurs theresults
vector is empty and thestd::string error
property ofReadResults
is filled with the exception message.This patch is compatible with the two functions
readBarcodeFromPixmap
andreadBarcodeFromPixmap
which returned only oneReadResult
with error inside it directly.In #565 we discussed to add a default value for
maxSymbols
: I did not add it because it wasn't usable from the JavaScript side (an error was raised by the browser saying I had to give 5 arguments and only 4 were found).About the JavaScript way to use the result: the
register_vector
emscripten function is creating a new interface and some JavaScript boilerplate code should be added to use the result.See the binding.h emscripten file to view all methods available to interact with a vector: https://github.com/emscripten-core/emscripten/blob/98b618f09bc106d401c0045fa7252f1cd15bd3c0/system/include/emscripten/bind.h#L1894
User can either create C-like for loops with the
.size()
and.get(int i)
methods or create a JavaScript Iterator to wrap the received result.I've updated the demo_reader to show how to create and use the Iterator way.
The Iterator can be used with two different style: either directly loop on it (see
showScanResults
) or use it to create a native Javascript Array (seeshowImageWithResults
).If you prefer to not show this Iterator way, I can update the demo_reader to use only C-style for loops.
The demo_reader has been improved to show result in an ordered list in text and to add the result index on each barcode found in the image.