Skip to main content

How do I down scale a jpeg image while decoding it?

3 replies [Last post]
demonduck
Offline
Joined: 2008-03-14
Points: 0

I need to be able to down scale a jpeg image while decoding it. When my applet tries to show a large image in a browser or on a computer that doesn't support the new plugin, the default memory limit causes my applet to fail while decoding that large image.

90meg just isn't enough for images greater than 6000x3000 to be reliably decoded.

There has been some mention that there will be a scaling feature added to the JPEG standard for decoding.

See: http://jpegclub.org/

Will this feature be added quickly to Java's current jpeg codec?

Is there a way now to scale the image without making the large image first then applying an AffineTransform to it?

There is a getScaledInstance() method for Image but I need a BufferedImage and ImageReader -- strangely enough -- uses the getScaledInstance() for Image so when using ImageIO almost every method that returns an image returns a BufferedImage except getScaledInstance()

Yet another flaw in the highly regarded BufferedImage API.

So if someone has a way to down scale a jpeg image while decoding it could you please post a snippet that shows how to do that and return a BufferedImage?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fred34
Offline
Joined: 2004-06-19
Points: 0

Yes there is a way to do it and yes it is part of every Java image codec. Though, to be honest I'm not sure why I'm helping considering all you ever do is complain here. No it's not a missing feature from the BufferedImage API since that API has nothing to do with image loading/saving. This method isn't a technical resize and is actually a decimation option, but for such large images it shouldn't cause a problem. You can always ask for a certain level of decimation and then apply a Graphics2D transform for the final stage of resizing. If you actually ever bothered reading the java API before complaining of a missing feature you might have found these methods in the ImageIO API:

Firstly, canSetSourceRenderSize() and setSourceRenderSize() which allow you to "scale the image without making the large image first then applying an AffineTransform to it"

Alternatively, since not many codecs actually support this, in IIOParam:

setSourceSubsampling(int sourceXSubsampling, int sourceYSubsampling, int subsamplingXOffset, int subsamplingYOffset)

which allows you to specify that every nth row/column of the image is ignored, thus creating a smaller picture.

I've tried these and they actually work quite well.

rkalla
Offline
Joined: 2006-09-13
Points: 0

logged in just to specifically thank fred for that reply; I authored an image-scaling library for Java (imgscalr) and wasn't even aware of this I'm embaressed to say... this opens up all sorts of possibilities.

demonduck
Offline
Joined: 2008-03-14
Points: 0

Yes, yes -- heard it all before. I'm supposed to quietly nod along behind our good shepherds while Java has become pariah on the desktop and 10 years invested in becoming a Java programmer are trashed -- and SUN's done so well that Oracle can
buy it for a song. Sorry....

But as to your solution -- thank you. The JPEG codec does not support setSourceRenderSize() but setSourceSubsampling() seems to work well enough for my purposes. I still have to test to see if it really does reduce memory requirements but looking good so far.