ZXing hates JFIF standard 1.02 ??

94 views
Skip to first unread message

Steph

unread,
Aug 5, 2013, 6:37:12 AM8/5/13
to zx...@googlegroups.com
Hi !

I've generated a file with the QR Code here in copy namedzxing.pngwith this :
ByteArrayOutputStream out = QRCode.from("Zebra Crossing is magic !").to(ImageType.PNG).stream();
FileOutputStream fout = new FileOutputStream(new File("zxing.png"));
fout.write(out.toByteArray());
fout.flush();
fout.close()

Reading the image file with this :
File file = new File("zxing.png");
BufferedImage img = ImageIO.read(file);
binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(img)));
result = new MultiFormatReader().decode(binaryBitmap);
System.out.println("QR Code : " + result.getText());
GREAT :) I've got the text "QR Code : Zebra Crossing is magic !" 

Now i've opened zxing.png on my computer, showing it on my screen, and I took a photo of the screen, here in copy named zxing_photo_fullsize.jpg .
Reading this file throws me a NotFoundException :-/ Maybe too big picture (1920x1080px) ?

So... let's resize zxing_photo_fullsize.jpg with Gimp in 400x225 ; that gives the file zxing_photo_resized400x225_gimp.jpg
GREAT :) decoding this file gives me the right sentence.

So i've coded its resize :
BufferedImage originalImage = ImageIO.read(new File("zxing_photo_fullsize.jpg")); // 1920x1080
BufferedImage scaledImg = new BufferedImage(400, 225, BufferedImage.TYPE_INT_RGB);
Graphics2D g = scaledImg.createGraphics();
g.drawImage(originalImage, 0, 0, 400, 225, null);
g.dispose();
File resizedImage = new File("zxing_photo_fullsize_400x225.jpg
");
ImageIO.write(scaledImg, "jpg", resizedImage);
return scaledImg;

DAMNED :o( Exception NotFoundException thrown ! Why ??

Have a look at those files ; First, the fullsize shot of the screen with my camera :
$ mediainfo zxing_photo_fullsize.jpg && file zxing_photo_fullsize.jpg 
General
Complete name                            : zxing_photo_fullsize.jpg
Format                                   : JPEG
File size                                : 350 KiB
Image
Format                                   : JPEG
Width                                    : 1 920 pixels
Height                                   : 1 080 pixels
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Compression mode                         : Lossy
zxing_photo_fullsize.jpg: JPEG image data, JFIF standard 1.02


The photo resized by my script :
$ mediainfo zxing_photo_fullsize_400x225.jpg && file zxing_photo_fullsize_400x225.jpg
General
Complete name                            : zxing_photo_fullsize_400x225.jpg
Format                                   : JPEG
File size                                : 11.0 KiB
Image
Format                                   : JPEG
Width                                    : 400 pixels
Height                                   : 225 pixels
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Compression mode                         : Lossy
zxing_photo_fullsize_400x225.jpg: JPEG image data, JFIF standard 1.02


The photo resized manually with gimp :
$ mediainfo zxing_photo_resized400x225_gimp.jpg && file zxing_photo_resized400x225_gimp.jpg
General
Complete name                            : zxing_photo_resized400x225_gimp.jpg
Format                                   : JPEG
File size                                : 12.4 KiB
Image
Format                                   : JPEG
Width                                    : 400 pixels
Height                                   : 225 pixels
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Compression mode                         : Lossy
zxing_photo_resized400x225_gimp.jpg: JPEG image data, JFIF standard 1.01

The only difference is JFIF standard 1.02 (with my camera and my script) vs 1.01 (with gimp).

Do you know any issues of this kind ?
Is there a way to do otherwise ?

Thanks a lot !!

Best regards,
Steph
zxing.png
zxing_photo_fullsize.jpg
zxing_photo_fullsize_400x225.jpg
zxing_photo_resized400x225_gimp.jpg

Sean Owen

unread,
Aug 5, 2013, 8:11:09 AM8/5/13
to zx...@googlegroups.com
All images are read with javax.imageio in the JDK, so if anything 'hates' a format, it is not this library.

I'm having a hard time following what you are reporting, but it seems like image #4 works, while image #2 doesn't, when they are plainly very similar. That does sound like perhaps javax.imageio is not parsing the image correctly, or at least very slightly different and it's enough to make one fail. That sounds like an imageio issue.

#3 has severe Moiré distortion which is almost surely why it fails.

Steph

unread,
Aug 6, 2013, 3:00:57 AM8/6/13
to zx...@googlegroups.com
Thank you Sean for the following !

I've found the solution this night ... when I opened the files to watch them ;-)
Look at the files size : the 400x225 are 15Ko for one and 11Ko for the other (with Moiré).
That's an ImageIO issue, but only when writing the file : the compression is the problem  :(

@mannyvergel uses JPEGCodec and JPEGEncodeParam to set dpi and quality but thoses classes are now deprecated in Java7.
imgscalr makes also too much moiré :-/
At least, java-image-scaling does the job,even without the unsharpen filter :)

BufferedImage origBufImg = ImageIO.read(srcFile);
ResampleOp resampleOp = new ResampleOp(img_width, img_height);
//resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.Normal);
BufferedImage resizeBufImg = resampleOp.filter(origBufImg, null);

int extPos = srcFile.getName().lastIndexOf(".");
String newName = srcFile.getName().substring(0, extPos) + "_" + resizeBufImg.getWidth() + "x" + resizeBufImg.getHeight()
+ srcFile.getName().substring(extPos);
File destFile = new File(newName);
ImageIO.write(resizeBufImg, "jpg", destFile);

return resizeBufImg;
Reply all
Reply to author
Forward
0 new messages