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]

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;
}
}