Forums Register Login

Adjusting the size of an image (jpg)?

+Pie Number of slices to send: Send
I have some images that are very large and need to adjust the size of them downward but keep the original aspect ratio.

Can anyone point me to some sample code on how this can be done?

In short, what I need to do is:

1) Load an image from the database (I can handle that).
2) Determine the size of the image.
3) If the image is too large, determine the aspect ratio then resize it.
4) Stream it out to my web app (I can handle that).

Note that the image will be read/processed by a servlet, and I'd like the keep the Image2D stuff to a minimum if possible.

Thanks!
+Pie Number of slices to send: Send
java.awt.Image) has width(), height() and getScaledInstance() methods.
[ June 15, 2005: Message edited by: Joe Ess ]
+Pie Number of slices to send: Send
OK, I've done a little digging, but I'm not sure what I'm doing is the right/best way.

My images are stored in a database and I get them back as a byte[]. I also need to send them back out as a byte[] from the scaling method.

What I do is convert this byte[] to an ImageIcon, perform the calculations (see what ratio I need, etc.), use the Image.setScaledInstance, place this into a BufferedImage, and then finally into a ByteArrayOutputStream so I can get the final byte[].

The code looks something like this:



Is there a better (easier/faster) way?

Thanks!
+Pie Number of slices to send: Send
 

Originally posted by Darrin Smith:

Is there a better (easier/faster) way?



What you've done, if it works, is probably fine. We don't get a lot of control over image loading and coversion in Java.
I dont see what imageDataDAO is, but I'd probably get the image out of the database result set as an InputStream and feed that directly to ImageIO to get a BufferedImage. In practical terms, it's probably doing the same amount of work you are doing above. Make sure you invoke flush() on all Image instances when you are finished with them. There's some resources which don't get freed automatically.
+Pie Number of slices to send: Send
Well this doesn't seem to work.

It does get the image in the correct size and aspect ratio, but the image is displayed as one big black box!

Can anyone see the error of my ways here? I've seen examples that do something very similar to what I am trying so it must be something small.

BTW, thanks Joe, and yes, the ImageDataDAO is what gets the image out of the database as a byte array (uses Spring BTW).

Thanks!
[ June 15, 2005: Message edited by: Darrin Smith ]
+Pie Number of slices to send: Send
OK. I looked around in the attic and found a servlet where I was doing the same thing. Looks very much like your code, with the exception of using a -1 argument to the getScaledImage() call (resizes and preserves the aspect ratio):


I stripped out the code where it determines fileDir and fileName and caches the scaled instance since you are using a DB.
Are you sure your process to save the image to the DB works? What if you just grab it out of the db? Does it display properly?
+Pie Number of slices to send: Send
Hi Joe,

Thanks for all of your work.

Yes, the image is saved correctly and it will display just fine when I show it full size.

Note though that I think I've got a solution!

I did a little test writing the image out to a file and, sure enough, it too was black. I then changed from a Graphics2D to Graphics and did the same thing...BINGO, now the image gets saved correctly!

Was I doing something wrong by using Graphics2d instead of Graphics?

Here is my test code (doesn't pass back a byte[], but that will come next):



+Pie Number of slices to send: Send
That's odd. The only thing I see different is that it doesn't work when you use createGraphics() but works when you use getGraphics() though those methods are documented to do the same thing (i.e. return a graphics instance).
I told you this subject was a black hole.
Use what works
Don't forget to free up those Graphics instances with a call to dispose().
+Pie Number of slices to send: Send
 

Originally posted by Joe Ess:
Don't forget to free up those Graphics instances with a call to dispose().



Sure will!

Thanks.
+Pie Number of slices to send: Send
You can do the same thing using AffineTransforms which I have found to consume less memory

instead of:


you might try:



and then once you have the BufferedImage.. you can manipulate it this way



And this is not really like modifying the same BufferedImage. op.filter returns a BufferedImage and the null value is supposed to be a destination BufferedImage I just overwrite what I was using before.

Anyone see any caveats there? I haven't had any problems yet.
This is also used from a servlet. Some other gotchas are trying to manipulate a file before you have it read in. Which is why I used the IIOPReadProgressListener..

also.. I'm not a graphics programming expert.. and this code is just hacked from my real code..
[ July 03, 2005: Message edited by: marcus g. ]
+Pie Number of slices to send: Send




I don't understand this part of your code...

It looks like it does the same thing no matter what..

Phil
[ August 26, 2008: Message edited by: Phil Wilson ]
I yam what I yam and that's all that I yam - the great philosopher Popeye. Tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 10602 times.
Similar Threads
Image size
Crop an image in Java
How to maintain Aspect Ratio of Image using struts2
Fixed with/heigth ratio for Swing frame ?
Image component problem.
More...

All times above are in ranch (not your local) time.
The current ranch time is
Apr 15, 2024 22:45:14.