2012-11-28 26 views
57

jest już pytanie jak to link na StackOverflow i zaakceptowanej odpowiedź brzmi "odlew":Java konwersja obrazu do BufferedImage

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

W moim programie Staram:

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; 

Niestety ja się uruchomić błąd czasu:

sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage

Oczywiście odlewanie nie działa.
Pytanie brzmi: Jaki jest (lub jest) właściwy sposób przekształcania obrazu w obraz BufferedImage?

+0

jeśli chcesz przeskalować buforowany obraz spróbować spróbować [http://stackoverflow.com/questions/4216123/ sposób do powiększenia skali A-BufferedImage] [1] [1]: http://stackoverflow.com/questions/4216123/how-to-scale-a-buffere dimage – user902383

+6

Dla zapisu NIE jest to kompilator, który to mówi. Widzisz błąd runtime ... nie błąd kompilacji. –

+1

Masz rację. Dzięki za wskazanie tego. Odpowiednio edytuję pytanie. –

Odpowiedz

74

Z 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

Czy naprawdę konieczne jest skopiowanie całej pamięci obrazu? –

+0

@ TomášZato Myślę, że to jedyny sposób na konwersję z "obrazu" na "obraz buforowy". Nie powinieneś martwić się pamięcią podczas korzystania z Javy. –

+4

@SriHarshaChilakapati 'Nie powinieneś martwić się pamięcią podczas korzystania z Javy. Sądząc po przeciętnym zużyciu pamięci przez aplikacje Java, inni deweloperzy zdecydowanie nie troszczą się o pamięć. –

2

Jeśli wracając do sun.awt.image.ToolkitImage można rzutować obraz na to, a następnie użyj getBufferedImage() uzyskać BufferedImage.

Więc zamiast ostatniej linii kodu, gdzie jesteś odlewania byłoby po prostu zrobić:

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

nie działa dla OpenJDK – AvrDragon

+4

1) Nie można korzystać z klas z pakietu 'sun'. Nie można zagwarantować, że będą dostępne w pakietach JDK innych niż Oracle. 2) Metoda 'getBufferedImage()' działa tylko wtedy, gdy buforowany obraz został wygenerowany wewnętrznie przez 'TookitImage'. Najczęściej (99%) nie jest, więc zwracana wartość to 'null'. [Źródło odniesienia] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/awt/image/ToolkitImage.java#ToolkitImage.getBufferedImage%28%29) – kevinarpe

16

Jeden sposób obsłużyć to, aby utworzyć nowy BufferedImage, i powiedzieć, że to obiekt graficzny zwrócić przeskalowany obraz w nowym obrazie 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); 

To powinno wystarczyć bez rzutowania.

+1

Nigdy nie zapomnij usunąć utworzonych instancji graficznych. –

+0

Jak "pozbyć się stworzonych interfejsów graficznych"? – Buffalo

+2

dodajesz buffered.getGraphics(). Dispose(); do kodu. – salbeira

1

Jeśli używasz Kotlin, możesz dodać metodę rozszerzenia do Obrazu w taki sam sposób, jak sugeruje 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 
} 

i używać go tak:

myImage.toBufferedImage()