Closed sachin321123 closed 3 years ago
Hi @sachin321123,
Since everything is happening inside the browser, we support every format supported natively by the web browser.
This is the relevant code from the example:
scanImageElement.src = URL.createObjectURL( file );
await scanImageElement.decode();
const imageFrame = BlinkIDSDK.captureFrame( scanImageElement );
As you can see, we rely on the HTML <img>
element. And everything that renders inside that element can be passed to the SDK with the auxiliary method BlinkIDSDK.captureFrame()
.
Like the previous point, since everything is happening inside the browser, there is no file size limit. However, keep in mind that the bigger the size, the longer it will take for processing to complete.
With the bigger resolution, one can expect better results :)
The minimal resolution we would advise is 720p, i.e. 1280x720 px.
Also, it's worth noting that it's a good practice to provide document images where there is padding between document edges and image edges.
I hope this helps.
Sincerely, Vjekoslav
Hello @vjekoart Thanks for the information. I have found a setting:- // Create instance of recognizer const BlinkIdRecognizer = await BlinkIDSDK.createBlinkIdRecognizer( sdk ); // Retrieve current settings const settings = await BlinkIdRecognizer.currentSettings(); // Update desired settings settings[ "scanCroppedDocumentImage" ] = true; // Apply settings await BlinkIdRecognizer.updateSettings( settings );
Witht the below settings, I am able to scan some even lower resolution images, however it expects no padding, so fails to scan high resolution images with some padding. I was thinking to add both settings, if one fails add another setting. For that I need to create 2 intsances of recognizeRunner with an updated recognizer, Howver I get an exception while doing this:- Unhandled Rejection (DataCloneError): Failed to execute 'postMessage' on 'Worker': ArrayBuffer at index 0 is already detached.
Can you please let me know if there is some other way to apply such setting.
Regards, Sachin
Hi @sachin321123,
Sorry for the delayed response.
It's possible to achieve the functionality you described, but it has a couple of specific problems. They're also the cause of the error you're getting.
The root of the error you're getting lies within the captureFrame
method and the ImageData interface.
I'll try to explain further, assuming that you're familiar with the example code we provided.
imageFrame
is defined.
ImageData
interface, i.e. this variable holds the data of an image you want to scan.ArrayBuffer
structure.recognizerRunner.processImage
method, the image data is sent from the main thread to the web worker.
ImageFrame
interface. Once the data is read, the ArrayBuffer
in the imageFrame
variable becomes detached - empty.imageFrame
variable contains empty property, and therefore data cannot be extracted. This causes an error that you see in the browser console.The main idea of this solution is to create a new instance of the imageFrame
variable before every call to the recognizerRunner.processImage
method.
I've changed the relevant part of the original example to support your approach. New logic would scan the same image twice if the first scanning process wasn't successful.
Scanning logic has been moved from the startScan
function to the scanImage
function for better readability.
/**
* Scan single side of an identity document with web camera.
*/
async function startScan( sdk, fileList )
{
document.getElementById( "screen-start" )?.classList.add( "hidden" );
document.getElementById( "screen-scanning" )?.classList.remove( "hidden" );
// Make sure that image file is provided
let file = null;
const imageRegex = RegExp( /^image\// );
for ( let i = 0; i < fileList.length; ++i )
{
if ( imageRegex.exec( fileList[ i ].type ) )
{
file = fileList[ i ];
}
}
if ( !file )
{
alert( "No image files provided!" );
return;
}
// Prepare image element that will be used with `captureFrame` method
scanImageElement.src = URL.createObjectURL( file );
await scanImageElement.decode();
// Start scan
console.log( "Trying to scan uncropped image..." );
let results = await scanImage( sdk, scanImageElement, false );
if ( results === null )
{
console.log( "Trying to scan cropped image..." );
results = await scanImage( sdk, scanImageElement, true );
}
console.log( "Result", results || "could not extract information" );
// Hide scanning screen and show scan button again
inputImageFile.value = "";
document.getElementById( "screen-start" )?.classList.remove( "hidden" );
document.getElementById( "screen-scanning" )?.classList.add( "hidden" );
}
async function scanImage( sdk, scanImageElement, cropped )
{
// 1. Create a recognizer object which will be used to recognize a single image or stream of images.
//
// Generic ID Recognizer - scan various ID documents
const genericIDRecognizer = await BlinkIDSDK.createBlinkIdRecognizer( sdk );
if ( cropped )
{
const settings = await genericIDRecognizer.currentSettings();
settings[ "scanCroppedDocumentImage" ] = true;
await genericIDRecognizer.updateSettings( settings );
}
// 2. Create a RecognizerRunner object which orchestrates the recognition with one or more
// recognizer objects.
const recognizerRunner = await BlinkIDSDK.createRecognizerRunner
(
// SDK instance to use
sdk,
// List of recognizer objects that will be associated with created RecognizerRunner object
[ genericIDRecognizer ],
// [OPTIONAL] Should recognition pipeline stop as soon as first recognizer in chain finished recognition
false
);
// 3. Prepare image for scan action - keep in mind that SDK can only process images represented in
// internal CapturedFrame data structure. Therefore, auxiliary method "captureFrame" is provided.
const imageFrame = BlinkIDSDK.captureFrame( scanImageElement );
// 4. Start the recognition and await for the results
const processResult = await recognizerRunner.processImage( imageFrame );
// 5. If recognition was successful, obtain the result and display it
let results = null;
if ( processResult !== BlinkIDSDK.RecognizerResultState.Empty )
{
const genericIDResults = await genericIDRecognizer.getResult();
if ( genericIDResults.state !== BlinkIDSDK.RecognizerResultState.Empty )
{
results = genericIDResults;
}
}
// 6. Release all resources allocated on the WebAssembly heap and associated with camera stream
// Release memory on WebAssembly heap used by the RecognizerRunner
await recognizerRunner?.delete();
// Release memory on WebAssembly heap used by the recognizer
await genericIDRecognizer?.delete();
return results;
}
There is no need to change the main
function. Everything should work as expected with the same code.
I hope this helps. Feel free to respond here if you find any new problems.
Sincerely, Vjekoslav
Hi @sachin321123,
Have you managed to get the SDK to work as intended with this solution?
Sincerely, Vjekoslav
Hi @vjekoart Sorry for the late reply. Yes, I have managed to get the SDK work, I will close this issue.
Regards, Sachin Dhawan
Hello Team,
We are facing some issues while scanning some of the docs. Please let us know about the particular resolution which you are looking for or something else related to quality of images, which might be missed by us. Also, please let us know about the max file size and the extensions which are supported by Blink ID.
Please find below the details of our implementation.
As per our requirement, we should allow the user to upload the doc for scanning and restrict him from using the web camera. So, we are using Blink ID for that and we have single scan option available for us. Please find below some information of the recognizer, as we are directly creating the recognizer and recognizer running classes. Please find below the code snippets which can help:-
const genericIDRecognizer = await BlinkIDSDK.createBlinkIdRecognizer(sdk); const idBarcodeRecognizer = await BlinkIDSDK.createIdBarcodeRecognizer(sdk);
const recognizerRunner = await BlinkIDSDK.createRecognizerRunner( // SDK instance to use sdk, // List of recognizer objects that will be associated with created RecognizerRunner object [genericIDRecognizer],
false ); // 3. Prepare image for scan action - keep in mind that SDK can only process images represented in // internal CapturedFrame data structure. Therefore, auxiliary method "captureFrame" is provided.
let file = null; const imageRegex = RegExp(/^image\//); for (let i = 0; i < fileList.length; ++i) { if (imageRegex.exec(fileList[i].type)) { file = fileList[i]; } }
const imageFrame = BlinkIDSDK.captureFrame(document.getElementById(name)); const processResult = await recognizerRunner.processImage(imageFrame); let genericIDResults; if (processResult !== BlinkIDSDK.RecognizerResultState.Empty) { genericIDResults = await genericIDRecognizer.getResult(); }
Kindly let us know if anything else is required from our end.
Regards, Sachin