I am trying to resize an Image, the save it as a BufferedImage. If I do not scale the image, I works fine.
With the following code, a filename is passed in and converted to a BufferedImage this works fine Using g.drawImage(img, x, y, null); where img is the BufferedImage
public Sprite(String filename){
ImageIcon imgIcon = new ImageIcon(filename);
int width = imgIcon.getIconWidth();
int height = imgIcon.getIconHeight();
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics bg = bimg.getGraphics();
bg.drawImage(imgIcon.getImage(), 0, 0, null);
bg.dispose();
this.sprite = bimg;
}
The following method here does not work, it takes a filename, and a resize width. It resizes it, then converts it to a BufferedImage, but it does not work using g.drawImage(img, x, y, null); again where img is the BufferedImage.
public Sprite(String filename, int width){
ImageIcon imgIcon = new ImageIcon(filename);
Image img = imgIcon.getImage();
float h = (float)img.getHeight(null);
float w = (float)img.getWidth(null);
int height = (int)(h * (width / w));
Image imgScaled = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics bg = bimg.getGraphics();
bg.drawImage(imgScaled, 0, 0, null);
bg.dispose();
this.sprite = bimg;
}
So my question is, why isn’t the second block working?
You have a rounding issue…
Java will return result of a division based on the values you provide it…
For example…
Java has done an internal conversion, converting the value back to an
int, which simply truncates the decimal values.Instead, you need to encourage Java to return the result as decimal value…
So, you scale calculation
int height = (int)(h * (width / w))is actually returning0I would use a calculation more along the lines of
I’m sorry, I don’t quite remember the “technical” babble for all of this, but this is the general jest of the idea 😉
Updated
ImageIconuses a background thread to actually load the image pixels, but returns immediately after you call the constructor. This means that the image data may not be available for some time into the future.Use
ImageIO.read(new File(filename))instead. This will block until the image data has been read and will return aBufferedImage, which is significantly easier to deal with.