5

I'd like to check the dimensions of an image, and then size it down if the width exceeds a given threshold. When I load a 6MB JPEG image with ImageIO.read(), the BufferedImage allocates about 45MB of heap space. Is there a way to do a passthrough image resize without loading all the data into memory? I tried passing ImageIO.read() a File object, thinking it would stream the data from disk, but it doesn't help.

Boris Burtin
  • 811
  • 1
  • 7
  • 18

3 Answers3

3

Check out im4java and JMagick. Both use an extremely efficient external tool called ImageMagick for image manipulation. Im4Java calls the command-line app (does work in separate process), and JMagick calls it within the same process via JNI.

If I'm doing simple image manipulation (resizing, scaling, rotating, etc), I'd much rather let ImageMagick do it for me. It'll be faster, more reliable, and consume less memory than anything you'd implement in a similar amount of time.

Hope this helps!

Ben Burns
  • 14,978
  • 4
  • 35
  • 56
  • Thanks Ben. I'll check out the ImageMagick libraries for Java. – Boris Burtin May 17 '11 at 17:03
  • 1
    Agree with Ben; if high-efficiency is the way you need to go, using a native solution and calling out with Java is probably the only way that is going to happen. Resizing images is actually a resampling operation; you can't avoid it. Resampling requires a reduction algorithm picking and averaging pixel values; doing this in "chunks" in Java will require A LOT of custom code ontop of ImageReadParam pulling in sections at a time, sampling them and combining the results efficiently. In short, it will *suck*. – Riyad Kalla May 18 '11 at 16:22
3

I've used jmagick before with excellent results, however it can be fiddly to get it working in different environments (sticking the jars in the right place, making sure you've got the correct build of imagemagick, etc).

You might want to consider using imgscalr (http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library). It's an open source, pure java image manipulation library available under the Apache 2.0 license. Much much (much..) easier to use and faster than that horrendous Java2D stuff.

rcgeorge23
  • 31
  • 1
1

You can use ImageInfo to check the width and height of the image without loading it into memory. I do not know of a library that will allow you to re-size without loading the image in memory. 45MB is not all that much memory really. Can you just increase your heap size?

dennisjtaylor
  • 996
  • 1
  • 8
  • 17
  • 9
    "45MB is not all that much"... depends on your target platform. – EboMike May 17 '11 at 00:42
  • 1
    Hear hear! 45MB is no-go for high concurrency and memory-constrained devices! – Ben Burns May 17 '11 at 00:45
  • true. If your target platform does not allow you to load 45 MB you could consider doing image scaling on a separate server. – dennisjtaylor May 17 '11 at 00:55
  • 1
    If you have a separate server available. You're living a very spoiled life, Dennis :) – EboMike May 17 '11 at 01:03
  • @Ben Burns - what nutter would try to process 6Mb JPEGs on a high concurrency and memory constrained device? Get a COMPUTER man! – Stephen C May 17 '11 at 01:08
  • @Stephen - could be on a mobile device (=memory constrained), where the camera creates 8MP images with a high quality level, for example. – EboMike May 17 '11 at 01:09
  • @EboMike, yes. A mobile underwater device no less. We had speed/power constraints that caused us to go so far as to implement our own image kernel on an FPGA... http://www.linkedin.com/pub/benjamin-burns/2/629/505 – Ben Burns May 17 '11 at 01:18
  • 1
    The code would be running inside a highly-available server. I can't risk the possibility that a user brings down the entire server by attempting to convert a gigantic image (i.e. much bigger than the test file that I used). – Boris Burtin May 17 '11 at 17:11