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
Related
I am currently working on a website which involves a lot of images. The problem is all the images are uploaded by the user so I can't do anything to alter the images. The website runs quiet ok on local system but the speed drops too much on the server,it becomes too slow
I'd suggest you to use Timthumb. It creates a thumbnail by generating a URL on the fly and uses very minimal disk space.
If the users of your website are uploading the images, then I presume (there must be) an upload script. Inside of that script or directly after its execution you could compress or rescale the image to size needed on the website, shortening loading time. There is a PHP image processing library called ImageMagick here:
http://php.net/manual/en/book.imagick.php
There is the PHP GD image processing library here:
http://php.net/manual/en/book.image.php
I don't have much personal experience with them, but from my knowledge it looks like one will do the job. Off the top of my head, that's the best solution I can think of, and hopefully it works. There is not a lot you can change about your problem if you don't compress/scale the images, and these are probably your best options. Wish you the best.
We are constantly transferring gigabytes of compressed Tiffs overseas and it takes a long time for each batch of images to transfer. It is not uncommon for a batch to take over 6 hours to transfer. I would like to reduce the time to transfer a batch of images.
I understand that videos compress really well because most of the time each frame is generally very similar to the one before it and compression algorithms take advantage of that. In our scenario, the images often look similar to one another. Are there any image compression libraries I can use to take advantage of the fact that there is a lot of redundancy across images? Ideally I would want lossless compression.
Would it work if I turned the images into a video before transferring them and then turned them back to images on the other side? If this would work, what libraries would you recommend? I need to be able to call this from Java and preferably run it on Linux, but the library does not need to be written in Java. Windows could also be a possibility.
What I would try first:
Start from uncompressed tiffs (otherwise, it will be hard to find similarities).
tar them together (so they are contained within a single file, can be a specific range of images off course).
Then use a compression algorithm of your choice to see which one yields the best results (on the single file).
Easy enough to try out without much effort. How well it works depends on the source images themselves (and the compression algorithm used).
Alternative approach if the above does not yield enough results:
Make sure you have all uncompressed images.
Send over the first image.
Do a binary diff (or maybe diffing the hexdump) towards the next image.
Send over the diff file and apply it at the receiving end to reconstruct the image.
Repeat 3-4 for every image.
I personally don't think you will easily get good (lossless) results by using video compression algorithms (after all, they are specifically tailored to a different purpose).
I was wondering if it is possible to load a huge JPEG (see my previous question there) and save it / use it in a quickly-loadable format, without loading its fully decoded contents into memory.
The main idea is to have a file format (or a function I'm not aware of which would do that natively in Java) allowing to load dynamically a given area of the image, without loading 800MB of data.
I'm actually using a tiling algorithm to render the image, but it needs to load the full image (thanks to mKorbel and Gerard Le Blanc), but this "preloading" step remains quite long.
I don't figure out how to do that (and first of all, is it possible ?), since Google did not help me a lot (maybe bad-english searching ?)
I found what I needed there :
very large image manipulation and tiling
The Java JAI lib has a lot of features to handle these kind of problems, and is supported by Oracle, which means it is (theoretically) stable and sustainable.
Thanks to #BryanD !
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.
Before you all say 'thats already on here somewhere...' :-)
PLEASE let me say I have looked and not found a simple example of using JAI to tile multiple jpg's and save to disk without java heap errors or other memory problems
I cant find a complete working set of code anywhere - they all seem to be miswritten / unchecked or simply do not work....
Help me Some-BiWan Kenobi - you're my only hope!
How big are the images? You might be able to just increase the memory allocated to the JVM. If they are huge, then JPG might not be the right format, because you need to load the whole image into memory to compress it and write it out. You might have better luck writing a tiled TIFF, using JAI.
I asked a similar question here: Write swing component to large TIFF image using JAI