2014-12-13 120 views
1

我試圖訪問其中使用ImageIO.read(filePath)文件加載的BufferedImage像素,但我得到這個錯誤如何更改從文件加載的BufferedImage的圖像類型?

Exception in thread "Game" java.lang.ClassCastException: java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt 
    at com.package.graphics.Texture.<init>(Texture.java:29) 
    at com.package.graphics.Texture.loadTexture(Texture.java:40) 
    at com.package.Game.run(Game.java:71) 
    at java.lang.Thread.run(Unknown Source) 

在代碼中,其誤差就行了,是在構造函數中,看起來像這樣:

// Get the pixel array from the BufferedImage 
this.pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 

據我瞭解這一點,BufferedImage的是類型BufferedImage.TYPE_INT_RGBBufferedImage.TYPE_INT_ARGB的不是。因爲我在遊戲的其餘部分中使用了這些類型,所以我想知道是否有方法將加載的圖像從加載的類型轉換爲另一個類型。
在我的情況下,我想將圖像類型轉換爲BufferedImage.TYPE_INT_ARGB

回答

3

創建一個類型的新緩衝圖像你想

BufferedImage in = ImageIO.read(img); 
BufferedImage newImage = new BufferedImage(in.getWidth(), in.getHeight(), BufferedImage.TYPE_INT_ARGB); 

Graphics2D g = newImage.createGraphics(); 
g.drawImage(in, 0, 0, in.getWidth(), in.getHeight(), null); 
g.dispose(); 
+0

好,謝謝!但是你也必須在新的圖像上繪製舊圖像。 – 2014-12-13 09:56:35

+0

我會將其添加到您的答案中。 – 2014-12-13 09:57:01

+0

修復了一次只調用'createGraphics()'的代碼('getGraphics()'調用相同的代碼)。 – haraldK 2014-12-13 11:38:09

0

你告訴JVM是image.getRaster().getDataBuffer()返回DataBufferInt時,它的實際返回DataBufferByte。這是一個ClassCastException。您需要將返回值轉換爲正確的類型。

// Get the pixel array from the BufferedImage 
this.pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 
+0

是的,但是如果您閱讀完整個問題,您會發現我提到我不希望該圖像屬於「BufferedImage.TYPE_INT_ARGB」類型,因爲我的其他所有'BufferedImage'都是這種類型,而我按照@overflowed的建議解決了這個問題。不管怎麼說,多謝拉。 – 2014-12-13 10:27:20

3

稍微(好吧,我承認,相當多的)更詳細的,但在大多數情況下,更快,做同樣的內存更有效的方式,就是直接加載圖像到TYPE_INT_ARGB圖像。

如果您的圖片很大,您可以通過首先加載到byte類型中的方式從中受益頗多。如果圖像很小,則可能不值得使用額外的代碼,因爲您幾乎不會注意到其中的差異。

無論如何,你可以像這樣做:

// Create input stream 
ImageInputStream input = ImageIO.createImageInputStream(file); 

try { 
    // Get the reader 
    Iterator<ImageReader> readers = ImageIO.getImageReaders(input); 

    if (!readers.hasNext()) { 
     throw new IllegalArgumentException("No reader for: " + file); // Or simply return null 
    } 

    ImageReader reader = readers.next(); 

    try { 
     // Set input 
     reader.setInput(input); 

     // Configure the param to use the destination type you want 
     ImageReadParam param = reader.getDefaultReadParam(); 
     param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB)); 

     // Finally read the image, using settings from param 
     BufferedImage image = reader.read(0, param); 
    } 
    finally { 
     // Dispose reader in finally block to avoid memory leaks 
     reader.dispose(); 
    } 
} 
finally { 
    // Close stream in finally block to avoid resource leaks 
    input.close(); 
} 
+1

謝謝!我的圖像非常小(大約32x32像素),所以我不會使用此代碼,但我會讚揚它。 /TheDDestroyer12 – 2014-12-13 11:56:41