New issue 513 by gadnex: Maximum image dimensions for QR decode
http://code.google.com/p/zxing/issues/detail?id=513
What steps will reproduce the problem?
1. Using the code at the bottom of this post I try decoding two images as
attached.
2. 1st image is scanned document with barcode, directly from scanner.
3. 2nd image is same image as above, but resized with image tool to 25% of
original dimentions.
4. 1st image fails to find/decode qr code, but 2nd image works file.
What is the expected output? What do you see instead?
Decode image files irrespective of image dimentions, or throw exception is
max image dimentions are exceeded.
What version of the product are you using? On what operating system?
ZXing 1.5 Core and Java Se
Please provide any additional information below.
Here is my code:
InputStream inputStream = new
ByteArrayInputStream(uploadedFile.getContents());
BufferedImage myImage = ImageIO.read(inputStream);
LuminanceSource source = new BufferedImageLuminanceSource(myImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Decode QR code
Reader reader = new QRCodeReader();
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType,
Object>();
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
Result result = reader.decode(bitmap);
Attachments:
QR page.png 2.3 MB
QR page 25 percent.png 420 KB
Comment #1 on issue 513 by dswit...@gmail.com: Maximum image dimensions for
QR decode
http://code.google.com/p/zxing/issues/detail?id=513
(No comment was entered for this change.)
I just realised that the two sample images I uploaded where not exactly the
same, but from two different tests I performed for the same phenomenon.
Here is a new image at 25% of the size of the large image I uploaded
previously.
Attachments:
QR page 25 percent.png 365 KB
Comment #3 on issue 513 by sro...@gmail.com: Maximum image dimensions for
QR decode
http://code.google.com/p/zxing/issues/detail?id=513
Use the latest version of the code. If you can, restrict your scan to the
portion of the image known to contain the barcode. Otherwise not much else
can be done.
Thanks for the response.
Unfortunately the idea I am looking at would involve clients printing out
an A4 page with a QR code, signing it, scanning it in and uploading the
scan to our website or fax/emailing it.
In this scenario I would not have control over the scanning resolution or
area, but I could try to programatically resize the image before trying to
decode the QR code.
I do not neccesarily think there is a bug in ZXing to be fixed, but would
it be possible to point me in the right direction to determine the maximum
dimentions (pixels by pixels)? If we do find this value, it would be very
useful for everyone to add to the documentation (JavaDoc and/or Developer
Notes) of the decoder.
If you control the page, then great, you know where the QR code is. For
example if it's in the top left quadrant, you can tell this to the
framework by constructing a BufferedImageLuminanceSource out of just that
region of the image. This may succeed.
There is no issue of maximum dimensions here.
I experimented a bit on my own and wrote the following code to test my
theory:
---CODE START---
int myImageHeight = myImage.getHeight();
int myImageWidth = myImage.getWidth();
if (myImageHeight > 2048 || myImageWidth > 2048) {
double scaleFactor;
BufferedImage bdest;
if (myImageHeight >= myImageWidth) {
scaleFactor = 2048.0 / myImageHeight;
int newwidth = (int) (myImageWidth * scaleFactor);
bdest = new BufferedImage(newwidth, 2048, myImage.getType());
} else {
scaleFactor = 2048.0 / myImageWidth;
int newheight = (int) (myImageHeight * scaleFactor);
bdest = new BufferedImage(2048, newheight, myImage.getType());
}
Graphics2D g = bdest.createGraphics();
AffineTransform at = new AffineTransform();
at.setToScale(scaleFactor, scaleFactor);
g.drawRenderedImage(myImage, at);
myImage = bdest;
}
---CODE END---
This code basically resizes the original image so that neither the width of
height would exceed 2048 pixels, while maintaining the original aspect
ratio.
What I found was that when I have this code enabled, the big QR barcode I
uploaded to this issue decodes without any issues.
If I comment this code out and try the same image again, then ZXing throws
a NotFoundException as before.
Now I may be wrong, but this does seem to indicate a size limitation in
terms of image dimensions in pixels.
The value of 2048 pixels I chose is arbitrary and I doubt that this would
be the max value.
Also the way I resize the image is probably far from the optimal
performance.
There is no size limitation at all. But, it's possible that one image does
not decode while a slight variation on the same image does. That's what's
happening here I imagine. It's not true that in general resizing will 'fix'
this.
Over the weekend I did extensive testing to try to get my program to decode
the QR barcodes consistently. What I found was that there is indeed no size
limitation in terms of dimentions.
What I did find consistently however, was that programaticcaly resizing the
large images smaller did make them decode successfully, where the original
large images failed.
The strange thing is that for PNG files, I had to resize them so that the
longest edge is around 3200 pixels so that the QR decoding works. For
exactly the same images converted to a JPG, I had to resize them so that
the longest edge is around 1700 pixels so that the QR decoding works. I
also found that the my JPG versions are substantially larger in terms of
file size, when compared to the PNG versions.
It also struct me, that when I am resizing the images programatically, I am
not only changing their dimentions, I am also changing their memory usage.
Do you think there may be some sort of memory limits in one of the object
(class) types used in the implementation of ZXing QR decode?
I am not suggesting that the problem lies in the ZXing implementation, but
perhaps lower level in my JVM. I am currently using Sun/Oracle JDK 6 update
21 on the Windows platform.
It isn't a memory issue -- you would see a clear OutOfMemoryError.
Thanks very much for all your help over the last few days.
I am happy that I was able to find a way to get my application to decode QR
codes consistently, even though I have no idea why my workaround works.
I only hope that the information in this issue would prove to be useful to
other ZXing users with similar issues.
Issue 891 has been merged into this issue.
Just to note: as discussed in #891, there is a proven size limitation.
Most reasonable approach is to downsample as suggested already.