2012-11-28 64 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()