Resizing BufferedImage, SLOW?

I need to resize a BufferedImage that is of very high quality. The picture is as much as 8Mb, and that's why I want to downsize it before saving in my DB. Anyway, my routine workd fine on smaller pictures, but when the picture gets this big, it simply stops. Anyone knows a better way of resizing pictures? My code is:

BufferedImage img = ImageIO.read(picFile);

Image tmpimg = img.getScaledInstance(-1, 70, 0);

JLabel lbl =new JLabel("");

loadImage(tmpimg, lbl);

int w = tmpimg.getWidth(null);

int h = tmpimg.getHeight(null);

BufferedImage bi =new BufferedImage(w, h, BuffferedImage.TYPE_INT_RGB);

Graphics2D g2d = bi.createGraphics();

g2d.drawImage(tmpimg, 0,0, w, h,null);

g2d.dispose();

Then the bi should be right size, which it is normally, just that such large pictures stops the whole application. I have set -Xmx512m, and have a pretty good PC (1Gb+ RAM).

And the loadImage function is:

publicstaticvoid loadImage(Image image, Component comp)throws IOException

{

MediaTracker mt =new MediaTracker(comp);

mt.addImage(image, 0);

try

{

mt.waitForID(0);

}catch (InterruptedException e)

{

thrownew RuntimeException("Unexpected");

}

if (mt.isErrorID(0))

thrownew IOException("Error during image loading");

}

Help to find a better (quicker) way of resizing would be appreciated.

Thx

[2328 byte] By [mhaavea] at [2007-10-3 3:00:27]
# 1

For a 1000 x 1000 jpg of size 397KB I get

C:\jexp>java LoadingTest

img type = 5

older way after loadImage = 31

older way after drawImage = 31

older way total time= 63

newer way time = 0

compatible image type = 1

compatible way time = 0

import java.awt.*;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.*;

import javax.imageio.ImageIO;

import javax.swing.*;

public class LoadingTest

{

public static void main(String[] args) throws IOException

{

File picFile = new File("images/2004-07-h-full_jpg.jpg");

BufferedImage img = ImageIO.read(picFile);

System.out.println("img type = " + img.getType());

JLabel olderLabel = new JLabel("");

long start = System.currentTimeMillis();

BufferedImage older = scaleOlderWay(img, olderLabel);

long end = System.currentTimeMillis();

long duration = (end - start)/1000;

System.out.println("older way total time= " + duration);

olderLabel.setIcon(new ImageIcon(older));

start = System.currentTimeMillis();

BufferedImage newer = scaleNewerWay(img, false);

end = System.currentTimeMillis();

duration = (end - start)/1000;

System.out.println("newer way time = " + duration);

JLabel newerLabel = new JLabel(new ImageIcon(newer));

start = System.currentTimeMillis();

BufferedImage compatible = scaleNewerWay(img, true);

end = System.currentTimeMillis();

duration = (end - start)/1000;

System.out.println("compatible way time = " + duration);

JLabel compatLabel = new JLabel(new ImageIcon(compatible));

JPanel panel = new JPanel(new GridLayout(1,0, 5, 0));

panel.setOpaque(true);

panel.add(olderLabel);

panel.add(newerLabel);

panel.add(compatLabel);

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setContentPane(panel);

f.pack();

f.setVisible(true);

}

private static BufferedImage scaleOlderWay(BufferedImage source, Component c)

throws IOException

{

Image tmpimg = source.getScaledInstance(-1, 70, 0);

long start = System.currentTimeMillis();

loadImage(tmpimg, c);

long end = System.currentTimeMillis();

long duration = (end - start)/1000;

System.out.println("older way after loadImage = " + duration);

int w = tmpimg.getWidth(c);

int h = tmpimg.getHeight(c);

BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = bi.createGraphics();

start = System.currentTimeMillis();

g2d.drawImage(tmpimg, 0,0, w, h, null);

end = System.currentTimeMillis();

duration = (end - start)/1000;

System.out.println("older way after drawImage = " + duration);

g2d.dispose();

return bi;

}

private static void loadImage(Image image, Component comp) throws IOException

{

MediaTracker mt = new MediaTracker(comp);

mt.addImage(image, 0);

try

{

mt.waitForID(0);

} catch (InterruptedException e)

{

throw new RuntimeException("Unexpected");

}

if (mt.isErrorID(0))

throw new IOException("Error during image loading");

}

private static BufferedImage scaleNewerWay(BufferedImage source, boolean compat)

{

int w = 70;

int h = 70;

BufferedImage bi = compat ? getCompatibleImage(w, h)

: new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = bi.createGraphics();

// assuming width == height for source

double xScale = (double)w / source.getWidth();

double yScale = (double)h / source.getHeight();

AffineTransform at = AffineTransform.getScaleInstance(xScale, yScale);

g2d.drawRenderedImage(source, at);

g2d.dispose();

return bi;

}

private static BufferedImage getCompatibleImage(int w, int h)

{

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

GraphicsDevice gd = ge.getDefaultScreenDevice();

GraphicsConfiguration gc = gd.getDefaultConfiguration();

BufferedImage image = gc.createCompatibleImage(w, h);

System.out.println("compatible image type = " + image.getType());

return image;

}

}

74philipa at 2007-7-14 20:50:02 > top of Java-index,Security,Cryptography...
# 2
Hey, thank you very much :o)This works much better, no question about that. Now I can finish my application, and relax.Have a good day,Mads
mhaavea at 2007-7-14 20:50:02 > top of Java-index,Security,Cryptography...