Reading JPEGs in Java - java

I'm attempting to get a JPEG into a BufferedImage to display on a JPanel . However, javax.imageio.ImageIO.read() seems to be very fussy about the JPEGs it processes, often throwing an IIOException. The same JPEGs open fine in pretty much any image reader you'd care to name.
I've looked at Apache's Sanselan and JAI. But Sanselan can't process JPEGs and JAI isn't available for 64-bit Windows platforms and doesn't seem to be maintained (the last update was in 2006). A previous answer on StackOverflow suggested com.sun.image.codec.jpeg.JPEGCodec, but this was deprecated in Java 5 and has disappeared in 7.
Are these my only options? Are there really no Java libraries capable of robustly reading JPEGs into a BufferedImage?

Legacy Toolkit methods such as createImage and getImage are known to be more lenient than ImageIO.
Werner Randelshofer also wrote a Service Provider to read CMYK JPEGs with ImageIO.
By combining both approaches (try every possible ImageReader and then fallback to Toolkit) you will be able to handle a reasonable number of JPEG Images.
Reading JPEGs with CMYK profile may be a interesting read.

Related

Libdmtx vs ZXing for DataMatrix Decoding?

How reliable is ZXing's barcode localization for DataMatrix decoding compared to libdmtx?
I have a set of png image files of stickers (proprietary, so unfortunately I'm not able to share them) containing DataMatrix barcodes. These stickers sit on flat surfaces, have very nice quiet zones and are generally centered in the image, but suffer from inequal lighting conditions and slight dust, likely the largest obstacle to reliable decoding.
I'd like to use a modifiable Java library to decode them and it seems that ZXing is the only open-source option (open to other suggestions). However, upon running these images through the ZXing online decoder, I consistently get NO BARCODE FOUND, even on the cleanest images. In contrast, when I run the same images through proprietary online decoders, like Inlite's Free Online Barcode Reader, I get reliable decodes for all the images. My company has implemented a library in C that also reliable decodes the barcode images by processing them and calling libdmtx. Similarly, this online DataMatrix decoder built on libdmtx can also reliably read my image files.
Is the barcode localization in ZXing significantly inferior to libdmtx?
If I attempt the same preprocessing on the image files before I run them through ZXing, could I achieve similar results? I have a strong preference for a Java library (ZXing), but I may have no choice but to use libdmtx. Would appreciate any insight, thanks!
I had similar problem as you but on encoding side. As per my findings Zxing is certainly inferior to Libdmtx. We are using both libraries in house in C++ and Java project.
There is a case when Zxing breaks while generating barcode look at my comments here:
https://github.com/zxing/zxing/issues/624
However Libdmtx works flowless. The other free options you have in java world are (they are for encoding):
barcode4j
OkapiBarcode
Another alternative is the relatively new ZXing cpp port here: https://github.com/nu-book/zxing-cpp.
It contains a completely new DataMatrix detector that was meant to fix serious limitations of the Java upstream version. It was specifically designed to deal with low resolution images (module size as low as around 2 pixels) and symbols that have just the required 1 module quite zone and a busy background.
The following comparison is certainly not 'fair' but I just had the dmtxread utility of the libdmtx try my test set of images and it missed 3 of 17 samples and took a whooping 300 times as long compared to my code :).

Java ImageIO.write() takes up to 6 seconds

I am writing an web application where I need to send an image from servlet to client. Image is generated dynamically and is quite big(+-2MB). It might be jpeg, png, or gif.
Now, I am using ImageIO.write() to write the image to output stream, but its veeeery slow. It takes up to 6 seconds till the client see the image. I need to speed it up.
Any suggestions?
btw. I am aware of Looking for a faster alternative to ImageIO topic. But it didn't help me.
Since it's slow with PNG ImageMagick is not a solution and
I have tested JAI and it was even worse.
Thanks in advance
Edit:
To show you some code:
BufferedImage bi = [code to generate Image];
response.setContentType(mime);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi,"png",out);
I stripped down Exception handling for readability.
Image encoding in java is pretty slow in general but you may also want to ensure you have the native libraries installed as they make quite a noticeable difference in performance.
http://download.java.net/media/jai-imageio/builds/release/1.1/INSTALL-jai_imageio.html
Be aware that ImageIO by default uses temporary files as cache when creating ImageInputStreams and ImageOutputStreams. This can be switched off by calling ImageIO.setUseCache(false).
For a more detailed explanation see this answer.
Are you sure that the
ImageIO
takes so long - maybe there is another problem, e.g.
slow (network) connection to the client
the generation (calculation) of the image takes a lot of time

java library to create, convert or edit images

I have to create thumbnails with images uploaded by my users. The image formats can be PNG, JPG, GIF. I gave a try to java.awt and javax.imageio but it is hard to deal with all the cases (image too large, image too small, image in XXX format, image with transparency...). I would prefer a library simple and not so verbose.
What java library do you use to convert / edit / create images ?
you might like to explore JMagick
Well, we use ImageIO and Apache Sanselan, but JAI or - if you don't mind using native libaries - jmagick should do as well.
image too large, image too small, image in XXX format, image with transparency
I'm not sure there is a library that doesn't have constraints like that. Since the images might be PNG, JPG or GIF, the format problem shouldn't apply.
Transparency is format dependent and thus should not depend on the library.
I chose Scalr, not need for extra ImageMagick or JNI wrapper :
http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/
On the other hand, quality is better with JMagick (if you can compile it and make it work)
Snowbound has the RasterMaster Java Imaging SDK. There is a decompress_bitmap call that will read in PNG, JPG, GIF and many other formats. The IMG_resize_bitmap_bicubic method can then be used to make a nice thumbnail.
You can go to Snowbound and push the "free trial" button to get a 30-day free trial version. The SDK comes with a Thumbnails code sample. If you want to learn more about the methods above before you expose your email address you can view the online documentation at RasterMaster.com.
Full disclosure - yes, I work for Snowbound.

Getting the pixel value of a TIFF image in Java

The ImageIO package doesn't work with .tif images and I cannot create a BufferedImage (Class I'm more familiar with) from a .tif file.
How do I easily get the pixel value of a TIFF image in Java? How can I do it FAST?
I'm not experienced with image processing and some sample code would be greatly appreciated!
Thanks!
You will need the Java Advanced Imaging API: JAI in order to work with TIFF images.
From the JAI API description:
TIFF
In addition to the baseline specification, the encoder and decoder support PackBits, modified Huffman and CCITT bilevel encodings (fax), JPEG-in-TIFF (per TIFF Technical Note #2), and DEFLATE compression schemes, can handle images with 16- and 32-bit integral samples and 32-bit floating point samples, and can read and write tiled images of all supported data types. The decoder in addition can decompress LZW-compressed imagery.
Additional features may be addressed in the future.
A single page of a multi-page TIFF file may loaded most easily by using the page parameter with the "TIFF" operator which is documented in the class comments of javax.media.jai.operator.TIFFDescriptor. A code sample is included here to show a means of loading a single page of a multi-page TIFF file using the ancillary codec classes directly.
Try out some of these tutorials.

Reading JCS_YCCK images using ImageIO

I'm using ImageIO.read to process uploaded image files. The code is similar to
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(image.getContents()));
I've managed to solve most of the issues, but this one has left me clueless. The uploaded image has a JCS_YCCK profile, as defined in com.sun.imageio.plugins.jpeg.JPEG, which is not supported by com.sun.imageio.plugins.jpeg.JPEGImageReader. This leads to a nice stack trace similar to:
Caused by: javax.imageio.IIOException: Unsupported Image Type
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:910)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:885)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1326)
at com.example.ImageWriter.resizeEmbeddableImageInPlace(ImageWriter.java:231)
How can I process this type of JPEG using Java's ImageIO?
Update: I've tried Commons-Sanselan, indicated by an answer, but unfortunately it does not support JPEG files:
org.apache.sanselan.ImageReadException: Sanselan cannot read or write JPEG images.
at org.apache.sanselan.formats.jpeg.JpegImageParser.getBufferedImage(JpegImageParser.java:90)
at org.apache.sanselan.Sanselan.getBufferedImage(Sanselan.java:1264)
at org.apache.sanselan.Sanselan.getBufferedImage(Sanselan.java:1231)
One possible solution is to use the Java Advanced Imaging Image IO extensions. When properly installed, the conversion works out of the box.
The problem is that it does not play well with Maven, so I've asked Using Java Advanced Imaging with Maven. If that works out, this answer will be accepted.
I don't know for ImageIO, but you could use the Commons Sanselan library, which offers easy ways to access all sorts of images.

Categories