2012-11-28 42 views
57

书中有这样link StackOverflow上和接受的答案已经问题是“铸造”:Java的转换图像到BufferedImage的

Image image = ImageIO.read(new File(file)); 
BufferedImage buffered = (BufferedImage) image; 

在我的节目我尝试:

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 cannot be cast to java.awt.image.BufferedImage

显然铸造不起作用。
问题是:什么是(或有)将Image转换为BufferedImage的正确方法?

+0

, 试试这个 试试这个[http://stackoverflow.com/questions/4216123/如何按比例的-A-的BufferedImage] [1] [1]:http://stackoverflow.com/questions/4216123/how-to-scale-a-buffere dimage – user902383

+6

为了记录,这不是说这个的编译器。您实际上看到一个运行时错误...不是编译错误。 –

+1

你说得对。感谢您指出了这一点。我将相应地编辑问题。 –

回答

74

Java Game Engine

/** 
* Converts a given Image into a BufferedImage 
* 
* @param img The Image to be converted 
* @return The converted BufferedImage 
*/ 
public static BufferedImage toBufferedImage(Image img) 
{ 
    if (img instanceof BufferedImage) 
    { 
     return (BufferedImage) img; 
    } 

    // Create a buffered image with transparency 
    BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); 

    // Draw the image on to the buffered image 
    Graphics2D bGr = bimage.createGraphics(); 
    bGr.drawImage(img, 0, 0, null); 
    bGr.dispose(); 

    // Return the buffered image 
    return bimage; 
} 
+0

是否真的有必要复制整个图像内存? –

+0

@TomášZato我认为这是从'Image'转换为'BufferedImage'的唯一方法。使用Java时,您不应该担心内存。 –

+4

@SriHarshaChilakapati'您在使用Java时不应该担心内存。'从Java应用程序的平均内存消耗来看,其他开发人员绝对不会担心内存的问题。 –

2

如果要取回一个sun.awt.image.ToolkitImage,你可以投的形象是,然后用getBufferedImage()得到BufferedImage

因此,而不是代码的最后一行,你是铸造你只是做:

BufferedImage buffered = ((ToolkitImage) image).getBufferedImage(); 
+4

对OpenJDK不起作用 – AvrDragon

+4

1)使用'sun'软件包中的类不屑一顾。它们不保证在非Oracle JDK中可用。 2)方法'getBufferedImage()'只有在'TookitImage'内部生成缓冲图像时才能使用。大多数情况下(99%)它不是,所以返回值是'null'。 [源参考](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/awt/image/ToolkitImage.java#ToolkitImage.getBufferedImage%28%29 ) – kevinarpe

16

一种方式来处理,这是创建一个新的BufferedImage,并告诉它的图形对象绘制你的缩放图像进入新的BufferedImage:

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

这应该没有铸造的伎俩。

+1

永远不要忘记处理创建的图形实例 –

+0

如何“处理创建的图形接口”? – Buffalo

+2

您添加了一个buffered.getGraphics()。dispose();到代码。 – salbeira

1

如果您使用Kotlin,则可以使用Sri Harsha Chilakapati建议的相同方式向Image添加扩展方法。

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()