我正在尝试调整图像的大小,将其保存为BufferedImage。如果我不缩放图像,我工作得很好。
使用以下代码,会传入一个文件名并将其转换为BufferedImage。使用g.drawImage(img, x, y, null);
,img是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;
}
下面的方法不起作用,它需要一个文件名和一个调整大小的宽度。它会调整大小,然后将其转换为BufferedImage,但在img是BufferedImage的情况下,它无法再次使用g.drawImage(img, x, y, null);
。
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;
}
所以我的问题是,为什么第二块不起作用?
您有舍入问题。。。
Java将根据您提供的值返回除法结果…
例如。。。
int width = 100;
int w = 5;
int result = width / w
// result = 0, but it should be 0.5
Java进行了内部转换,将值转换回int
,只需截断十进制值。
相反,您需要鼓励Java以十进制值的形式返回结果。。。
int result = width / (float)w
// result = 0.5
所以,缩放计算int height = (int)(h * (width / w))
实际上是返回0
我会使用更多类似的计算
int height = Math.round((h * (width / (float)w)))
对不起,我不太记得这一切的"技术性"胡言乱语,但这只是这个想法的一般玩笑;)
更新
ImageIcon
使用后台线程实际加载图像像素,但在调用构造函数后立即返回。这意味着图像数据可能在未来的一段时间内不可用。
请改用ImageIO.read(new File(filename))
。这将阻塞,直到图像数据被读取,并将返回BufferedImage
,这明显更容易处理。
检查:
Image imgScaled = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
如果是null
还是imgScaled
,对我来说,你有一个null
。
忘记哪种情况,但有一种情况,当图像加载是一个阻塞和其他非阻塞方法时,这意味着API函数将返回,图像尚未加载。通常需要使用观察员。就像我说的,我忘了那是什么时候,但我遇到了那些情况!