Tried to use several libraries like ZXing, ZBar and their forks but didn't find way to scan barcode not from camera but from file.
Can someone point me to right direction? Preferably I'm looking into ZXing: how to scan image from file (not from camera).
Please.
In the end I've found solution. Code is (originated from here):
import com.google.zxing.*;
public static String scanQRImage(Bitmap bMap) {
String contents = null;
int[] intArray = new int[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());
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
try {
Result result = reader.decode(bitmap);
contents = result.getText();
}
catch (Exception e) {
Log.e("QrTest", "Error decoding barcode", e);
}
return contents;
}
Gradle referencing as:
dependencies {
compile 'com.google.zxing:core:3.2.1'
}
Usage:
InputStream is = new BufferedInputStream(new FileInputStream(file));
Bitmap bitmap = BitmapFactory.decodeStream(is);
String decoded=scanQRImage(bitmap);
Log.i("QrTest", "Decoded string="+decoded);
Related
I'm using this code for image compression before uploading the images :
public File saveBitmapToFile(File file) {
try {
// BitmapFactory options to downsize the image
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inSampleSize = 6;
// factor of downsizing the image
FileInputStream inputStream = new FileInputStream(file);
//Bitmap selectedBitmap = null;
BitmapFactory.decodeStream(inputStream, null, o);
inputStream.close();
// The new size we want to scale to
final int REQUIRED_SIZE = 75;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
inputStream = new FileInputStream(file);
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
FileOutputStream outputStream = new FileOutputStream(file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
return file;
} catch (Exception e) {
return null;
}
}
The problem is the original image will be affected and get resized.
How to compress images without overwriting and losing the original one?
Update 1 :
I changed the last part of the code to this but still doesn't work.
now the image wouldn't get resized
File new_file =new File("/storage/emulated/0/DCIM/Screenshots/tmp.png");
try
{
new_file.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
Log.d("Create File", "File exists?"+new_file.exists());
FileOutputStream outputStream = new FileOutputStream(new_file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
return file;
Update 2 :
I've changed the code to this so the problem is partly solved. Now I can have an original quality of each image in a file named tmp"+new Date()+".png but the original file still will be overwritten.
File new_file =new File(String.valueOf("/storage/emulated/0/DCIM/Screenshots/tmp"+new Date()+".png"));
try
{
new_file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(new_file, true);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
}
catch (IOException e)
{
e.printStackTrace();
}
Log.d("Create File", "File exists?"+new_file.exists());
FileOutputStream outputStream = new FileOutputStream(file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
Create a new File and make the FileOutputStream write to it, rather than writing to the original.
New Answer
Your case is quite unique, what if you try this:
Rather than directly using the Bitmap from InputStream, try use it's copy().
That way, the one that you compress will be the copy of the Bitmap. And you can compress that in your new FileOutputStream without modifying the original file.
And remove the second compression. Just dont do anything with your original file.
I am experiencing an EOF Exception as follows when attempting to read tiff files using iText 5.5.10
ExceptionConverter: java.io.EOFException
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:249)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:241)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:209)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:314)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:302)
at com.itextpdf.text.Image.getInstance(Image.java:428)
at com.itextpdf.text.Image.getInstance(Image.java:374)
at TiffToPdf.main(TiffToPdf.java:137)
The code I am using is:
byte[] data = null;
Image img = null;
try {
data = Files.readAllBytes(Paths.get("tiff.tif"));
img = Image.getInstance(data, true);
}
catch (Exception e) {
e.printStackTrace();
}
I have tried skipping the Image step and using the TiffImage class explicitly but I experience the same error.
byte[] data = null;
Image img = null;
try {
data = Files.readAllBytes(Paths.get("tiff.tif"));
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
RandomAccessSource fileBytes = factory.createSource(data);
RandomAccessFileOrArray s = new RandomAccessFileOrArray(fileBytes);
img = TiffImage.getTiffImage(s, true, 1, true);
}
catch (Exception e) {
e.printStackTrace();
}
I noticed that there are 2 classes within iText called TIFFFaxDecompressor and TIFFFaxDecoder but I haven't been able to find any resources online on how to use them.
with your given tiff image, the following code does worked for me i.e., converted to pdf successfully.
byte[] data = null;
com.itextpdf.text.Image img = null;
try {
//System.out.println(Paths.get("src/main/resources/tiff.tif"));
data = Files.readAllBytes(Paths.get("src/main/resources/file.tif"));
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
RandomAccessSource fileBytes = factory.createSource(data);
RandomAccessFileOrArray s = new RandomAccessFileOrArray(fileBytes);
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("src/main/resources/destination.pdf"));
document.open();
int pages = TiffImage.getNumberOfPages(s);
Image image;
for (int i = 1; i <= pages; i++) {
image = TiffImage.getTiffImage(s, i);
Rectangle pageSize = new Rectangle(image.getWidth(),
image.getHeight());
document.setPageSize(pageSize);
document.newPage();
document.add(image);
}
document.close();
} catch (Exception e) {
e.printStackTrace();
}
Recently I have a difficulty using zxing to decode bitmap. I search solutions on Internet and I have tried some of them.Here is my try:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.qrcode);
String result = DecodeUtils.decodeWithZxing(bitmap);
R.drawable.qrcode is a .jpg file.
And BarCodeUtil.java is:
public static String decodeWithZxing(Bitmap bitmap) {
MultiFormatReader multiFormatReader = new MultiFormatReader();
Map<DecodeHintType, Object> hints = new Hashtable<>();
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
multiFormatReader.setHints(hints);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
Result rawResult = null;
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
if (source != null) {
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(binaryBitmap);
} catch (ReaderException re) {
re.printStackTrace();
} finally {
multiFormatReader.reset();
}
}
return rawResult != null ? rawResult.getText() : null;
}
But when I run the above code,I got a exception:
com.google.zxing.NotFoundException
So I search the exception,someone think bitmap size causes this exception.Then I resize the bitmap size:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.zhifubao,options);
String result = DecodeUtils.decodeWithZxing(bitmap)
But it still does not work for me.
Is there a good solution to decode bitmap with a qrcode?
I know this is probably very late, but, that just means that no barcode was found in the image. See here
NotFoundException
Thrown when a barcode was not found in the image.
If anyone else ends up with the same problem, that is, cannot decode a barcode such as QRcode or upc, a possibility might be using the wrong colorspace of the bitmap. You might be attempting to use RGB when the data from the camera is actually in YUV.
Instead of RGBLuminanceSource, you should use PlanarYUVLuminanceSource as in the example here
your development tools is eclipse or android studio ?
if is android stuido:
in your project > app > build. gradel on add:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
then sync gradle.
I am new to Android Programming. I am using Zxing Library to create a QR code and save it as a png file so that i can share it and the other user can consume it. QR code is generated properly but when I try to read the same it some times reads it properly but many a times gives NotFoundException.
Code that I have written to read the QR code from file is standard. not sure how to find out the issue.
Uri selectedImage = intent.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
cursor.moveToFirst();
String picturePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
cursor.close();
Bitmap bMap = null;
try {
bMap = decodeUri(selectedImage);
int[] intbMapArray = new int[bMap.getWidth()*bMap.getHeight()];
bMap.getPixels(intbMapArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bMap.getHeight(), bMap.getWidth(), intbMapArray);
BinaryBitmap binBitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
Result result = null;
result = reader.decode(binBitmap);
if (genQRCodeUpdateFields(intent,result.getText())){
ToQRCode.setImageBitmap(bMap);
}
} catch (FileNotFoundException | NotFoundException | ChecksumException | FormatException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Failed to read code from "+ picturePath,
Toast.LENGTH_SHORT).show();
Reset();
}
I am trying to merge two TIFF images which are in form of FileInputStream into a single Tiff image. Although the image is getting merged the output file is coming up as Black. While comparing the original image and the converted image I could see that the bit depth of the converted image changes to 1. Could anybody provide a solution to this?
The code that I am using is:
public class MergerTiffUsingBuffer {
public static void main(String[] args) {
File imageFile1 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/FLAG_T24.TIF");
File imageFile2 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/CCITT_3.TIF");
try {
FileInputStream fis1 = new FileInputStream(imageFile1);
FileInputStream fis2 = new FileInputStream(imageFile2);
List<BufferedImage> bufferedImages=new ArrayList<>();
List<FileInputStream> inputStreams=new ArrayList<>();
inputStreams.add(fis1);
inputStreams.add(fis2);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("tiff");
ImageReader reader = (ImageReader) readers.next();
for(FileInputStream inputStream:inputStreams){
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
BufferedImage binarized = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),BufferedImage.TYPE_BYTE_BINARY);
ImageIO.write(binarized, "tiff", out);
bufferedImages.add(bufferedImage);
}
System.out.println(bufferedImages.size());
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
You seem to be a little confused about how to copy image data. Simply creating a new, blank image, by passing the dimensions of another image, will not copy it... So a fully black image is what I would expect after running your code.
Replace your for loop with something like this:
for (FileInputStream inputStream : inputStreams) {
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
BufferedImage image = reader.read(0, null); // a) BufferedImage is returned! b) null param is fine!
BufferedImage binarized = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// The following 7 lines is the important part you were missing:
Graphics2D g = binarized.createGraphics();
try {
g.drawImage(image, 0, 0, null);
}
finally {
g.dispose();
}
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
ImageIO.write(binarized, "tiff", out); // You probably want to check return value (true/false)!
bufferedImages.add(image);
}