Scan Barcode From An Image In Gallery Android
Solution 1:
You could use this class MultiFormatReader from ZXing library.
You have to get Gallery image in BitMap and convert it as this:
BitmapbMap= [...];
Stringcontents=null;
int[] intArray = newint[bMap.getWidth()*bMap.getHeight()];
//copy pixel data from the Bitmap into the 'intArray' array
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSourcesource=newRGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
BinaryBitmapbitmap=newBinaryBitmap(newHybridBinarizer(source));
Readerreader=newMultiFormatReader();
Resultresult= reader.decode(bitmap);
contents = result.getText();
UPDATE1
To manipulate big image, please have a look at :
https://developer.android.com/training/articles/memory.html
https://developer.android.com/training/displaying-bitmaps/manage-memory.html
You could use this property android:largeHeap to increase heap size.
Solution 2:
I have a working sample on how to implement this, if you reading in 2016 here is how I did it:
publicclassMainActivityextendsAppCompatActivityimplementsView.OnClickListener {
//initialize variables to make them globalprivate ImageButton Scan;
privatestaticfinalintSELECT_PHOTO=100;
//for easy manipulation of the resultpublic String barcode;
//call oncreate method@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//cast neccesary variables to their views
Scan = (ImageButton)findViewById(R.id.ScanBut);
//set a new custom listener
Scan.setOnClickListener(this);
//launch gallery via intentIntentphotoPic=newIntent(Intent.ACTION_PICK);
photoPic.setType("image/*");
startActivityForResult(photoPic, SELECT_PHOTO);
}
//do necessary coding for each ID@OverridepublicvoidonClick(View v) {
switch (v.getId()){
case R.id.ScanBut:
//launch gallery via intentIntentphotoPic=newIntent(Intent.ACTION_PICK);
photoPic.setType("image/*");
startActivityForResult(photoPic, SELECT_PHOTO);
break;
}
}
//call the onactivity result method@OverrideprotectedvoidonActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
//doing some uri parsingUriselectedImage= imageReturnedIntent.getData();
InputStreamimageStream=null;
try {
//getting the image
imageStream = getContentResolver().openInputStream(selectedImage);
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(), "File not found", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
//decoding bitmapBitmapbMap= BitmapFactory.decodeStream(imageStream);
Scan.setImageURI(selectedImage);// To display selected image in image viewint[] intArray = newint[bMap.getWidth() * bMap.getHeight()];
// copy pixel data from the Bitmap into the 'intArray' array
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(),
bMap.getHeight());
LuminanceSourcesource=newRGBLuminanceSource(bMap.getWidth(),
bMap.getHeight(), intArray);
BinaryBitmapbitmap=newBinaryBitmap(newHybridBinarizer(source));
Readerreader=newMultiFormatReader();// use this otherwise// ChecksumExceptiontry {
Hashtable<DecodeHintType, Object> decodeHints = newHashtable<DecodeHintType, Object>();
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
decodeHints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
Resultresult= reader.decode(bitmap, decodeHints);
//*I have created a global string variable by the name of barcode to easily manipulate data across the application*//
barcode = result.getText().toString();
//do something with the results for demo i created a popup dialogif(barcode!=null){
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle("Scan Result");
builder.setIcon(R.mipmap.ic_launcher);
builder.setMessage("" + barcode);
AlertDialogalert1= builder.create();
alert1.setButton(DialogInterface.BUTTON_POSITIVE, "Done", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterface dialog, int which) {
Intenti=newIntent (getBaseContext(),MainActivity.class);
startActivity(i);
}
});
alert1.setCanceledOnTouchOutside(false);
alert1.show();}
else
{
AlertDialog.Builderbuilder=newAlertDialog.Builder(this);
builder.setTitle("Scan Result");
builder.setIcon(R.mipmap.ic_launcher);
builder.setMessage("Nothing found try a different image or try again");
AlertDialogalert1= builder.create();
alert1.setButton(DialogInterface.BUTTON_POSITIVE, "Done", newDialogInterface.OnClickListener() {
@OverridepublicvoidonClick(DialogInterface dialog, int which) {
Intenti=newIntent (getBaseContext(),MainActivity.class);
startActivity(i);
}
});
alert1.setCanceledOnTouchOutside(false);
alert1.show();
}
//the end of do something with the button statement.
} catch (NotFoundException e) {
Toast.makeText(getApplicationContext(), "Nothing Found", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (ChecksumException e) {
Toast.makeText(getApplicationContext(), "Something weird happen, i was probably tired to solve this issue", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (FormatException e) {
Toast.makeText(getApplicationContext(), "Wrong Barcode/QR format", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (NullPointerException e) {
Toast.makeText(getApplicationContext(), "Something weird happen, i was probably tired to solve this issue", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
}
}
Solution 3:
I'm in between of same scenario, where it throw NotFoundException, official doc says
Thrown when a barcode was not found in the image. It might have been partially detected but could not be confirmed.
First level solution at some extend @Laurent answer worked almost for every sample I have but failed for few.
Next level solution adding decodeHints before to reader.decode(..) suggested by @Lucien Mendela did the trick.
Hashtable<DecodeHintType, Object> decodeHints = new Hashtable<DecodeHintType, Object>();
decodeHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE); // Not required in my case
decodeHints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
But final things that worked for me
- If you have big image you may have to scale down.
- It also require a ~rectangle shape (421*402 in my case I did).
Reference Adding couple of similar issue filed across:
Tools you can use to validate image you have:
- qrdecode (Don't forgot to select check "Produce debug output" for debug info)
- Zxing Decoder online
Solution 4:
First, of course, read the image from the gallery (this can be in your activity): Help by
IntentpickIntent=newIntent(Intent.ACTION_PICK);
pickIntent.setDataAndType( android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(pickIntent, 111);
After that, just get the image uri on the activity result and then ZXing will do the magic:
@OverrideprotectedvoidonActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
//the case is because you might be handling multiple request codes herecase111:
if(data == null || data.getData()==null) {
Log.e("TAG", "The uri is null, probably the user cancelled the image selection process using the back button.");
return;
}
Uriuri= data.getData();
try
{
InputStreaminputStream= getContentResolver().openInputStream(uri);
Bitmapbitmap= BitmapFactory.decodeStream(inputStream);
if (bitmap == null)
{
Log.e("TAG", "uri is not a bitmap," + uri.toString());
return;
}
intwidth= bitmap.getWidth(), height = bitmap.getHeight();
int[] pixels = newint[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
bitmap.recycle();
bitmap = null;
RGBLuminanceSourcesource=newRGBLuminanceSource(width, height, pixels);
BinaryBitmapbBitmap=newBinaryBitmap(newHybridBinarizer(source));
MultiFormatReaderreader=newMultiFormatReader();
try
{
Resultresult= reader.decode(bBitmap);
Toast.makeText(this, "The content of the QR image is: " + result.getText(), Toast.LENGTH_SHORT).show();
}
catch (NotFoundException e)
{
Log.e("TAG", "decode exception", e);
}
}
catch (FileNotFoundException e)
{
Log.e("TAG", "can not open file" + uri.toString(), e);
}
break;
}
}
Post a Comment for "Scan Barcode From An Image In Gallery Android"