Java将图像转换为BuffereImage
StackOverflow上已经有类似的问题,公认的答案是“铸造”: 在我的程序中,我尝试:Java将图像转换为BuffereImage,java,image,casting,bufferedimage,Java,Image,Casting,Bufferedimage,StackOverflow上已经有类似的问题,公认的答案是“铸造”: 在我的程序中,我尝试: final float FACTOR = 4f; BufferedImage img = ImageIO.read(new File("graphic.png")); int scaleX = (int) (img.getWidth() * FACTOR); int scaleY = (int) (img.getHeight() * FACTOR); Image image = img.getScal
final float FACTOR = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = (BufferedImage) image;
不幸的是,我得到了运行时错误:
无法将sun.awt.image.ToolkitImage转换为java.awt.image.BufferedImage
显然,铸造不起作用。问题是:将图像转换为BuffereImage的正确方法是什么
如果您要返回一个
sun.awt.image.ToolkitImage
,则可以将该图像强制转换为该图像,然后使用获取缓冲区图像
因此,您只需执行以下操作,而不是最后一行代码:
BufferedImage buffered = ((ToolkitImage) image).getBufferedImage();
处理此问题的一种方法是创建新的BuffereImage,并告诉其图形对象将缩放图像绘制到新的BuffereImage中:
final float FACTOR = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
buffered.getGraphics().drawImage(image, 0, 0 , null);
如果你使用Kotlin,你可以像Sri Harsha Chilakapati建议的那样为图像添加扩展方法
fun Image.toBufferedImage(): BufferedImage {
if (this is BufferedImage) {
return this
}
val bufferedImage = BufferedImage(this.getWidth(null), this.getHeight(null), BufferedImage.TYPE_INT_ARGB)
val graphics2D = bufferedImage.createGraphics()
graphics2D.drawImage(this, 0, 0, null)
graphics2D.dispose()
return bufferedImage
}
然后像这样使用它:
myImage.toBufferedImage()
如果要缩放缓冲图像,请尝试此[[1]:请注意,不是编译器说的。您实际上看到的是运行时错误…不是编译错误。您是对的。感谢您指出这一点。我将相应地编辑问题。@user902383,即使他们没有直接回答我的问题-这些也是很好的解决方案。OP:Method
ImageIO的小问题。read(File)
通过签名返回一个buffereImage
。()无需先指定一个Image
变量,然后强制转换为typebuffereImage
。这可能会让阅读代码的人感到困惑。永远不要忘记处理创建的图形实例如何“处理创建的图形界面”?BuffereImage构造函数中的类型是否应与getScaledInstance中的类型匹配?不,该类型类似于ARGB或RGBA,即图像数据的内部存储方式-选择应用程序最自然的类型;键入BuffereImage时只需查看自动完成。[自动完成]要查看所有选项,1)不允许使用sun
包中的类。它们不保证在非Oracle JDK中可用。2)方法getBufferedImage()
仅在缓冲映像由TookitImage
内部生成时有效。大多数情况下(99%)它不是,所以返回值是代码> null < /C> > @ SRiHARSHIACHACKAPATAT<代码>使用java时不应该担心内存。< /Cuff>判断java应用程序的平均内存消耗,其他开发人员肯定不会担心内存。@ Tom Asz ZATO在我看来,你来自C++世界,思考。重用图像数据像素的内存。我的意思是,在这种情况下,不需要担心内存,因为GC将在Java中处理它。@SriHarshaChilakapati,这样垃圾收集器就不会消耗任何资源?GC只会从内存周围的代码中节省内存。它不会消除硬件限制。不是吗如果未加载图像
,his将不起作用,因为getWidth(null)
或getHeight(null)
将返回-1
,在这种情况下,我必须使用缓冲图像。键入\u INT\u RGB
而不是ARGB以获得正确的缩略图颜色
fun Image.toBufferedImage(): BufferedImage {
if (this is BufferedImage) {
return this
}
val bufferedImage = BufferedImage(this.getWidth(null), this.getHeight(null), BufferedImage.TYPE_INT_ARGB)
val graphics2D = bufferedImage.createGraphics()
graphics2D.drawImage(this, 0, 0, null)
graphics2D.dispose()
return bufferedImage
}
myImage.toBufferedImage()