2012-11-28 15 views
57

Es ist bereits ähnliche link auf Stackoverflow Frage und die Antwort akzeptiert wird "Casting":Java Umwandlung Bild BufferedImage

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

In meinem Programm Ich versuche:

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; 

Unfortunatelly Ich werde laufen Zeitfehler:

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

Offensichtlich funktioniert Casting nicht.
Frage ist: Was ist (oder gibt es) die richtige Art, Image zu BufferedImage zu konvertieren?

+0

wenn Sie gepufferte Bild skalieren möchten, versuchen diese try this [http://stackoverflow.com/questions/4216123/ how-to-scale-a-BufferedImage] [1] [1]: http://stackoverflow.com/questions/4216123/how-to-scale-a-buffere dimage – user902383

+6

Für den Datensatz ist es nicht der Compiler, der das sagt. Sie sehen tatsächlich einen Laufzeitfehler ... nicht einen Kompilierungsfehler. –

+1

Sie haben Recht. Danke, dass du darauf hingewiesen hast. Ich werde die Frage entsprechend bearbeiten. –

Antwort

74

Aus 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

Ist es wirklich notwendig, den gesamten Bildspeicher zu kopieren? –

+0

@ TomášZato Ich denke, das ist der einzige Weg, um von einem 'Image' in ein' BufferedImage' zu ​​konvertieren. Sie sollten sich bei der Verwendung von Java keine Gedanken über den Speicher machen. –

+4

@SriHarshaChilakapati 'Bei der Verwendung von Java sollten Sie sich keine Gedanken um den Speicher machen. 'Nach dem durchschnittlichen Speicherverbrauch von Java-Anwendungen sorgen sich andere Entwickler definitiv nicht um Speicher. –

2

Wenn Sie eine sun.awt.image.ToolkitImage immer wieder, können Sie das Bild auf das werfen, und dann getBufferedImage() verwenden, um die BufferedImage zu bekommen.

Anstatt also die letzte Zeile des Codes, wo man Sie werfen würde nur tun:

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

funktioniert nicht für OpenJDK – AvrDragon

+4

1) Es ist verpönt, Klassen aus dem 'Sonne'-Paket zu verwenden. Sie sind nicht garantiert in Nicht-Oracle-JDKs verfügbar. 2) Die Methode 'getBufferedImage()' funktioniert nur, wenn das gepufferte Bild intern von 'TookitImage' generiert wurde. Meistens (99%) ist es nicht, also ist der Rückgabewert "null". [Quellenreferenz] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/awt/image/ToolkitImage.java#ToolkitImage.getBufferedImage%28%29) – kevinarpe

16

Eine Möglichkeit, dies zu handhaben ist, eine neue BufferedImage zu schaffen, und sagen, es ist Grafik-Objekt Ihrer skalierten Bild zeichnen in den neuen 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); 

Das sollte den Trick ohne Gießen tun.

+1

Vergessen Sie nicht, erstellte Grafikinstanzen zu verwerfen –

+0

Wie "erstellt erstellte Grafikschnittstellen"? – Buffalo

+2

Sie fügen ein buffered.getGraphics() hinzu. Dispose(); zum Code. – salbeira

1

Wenn Sie Kotlin verwenden, können Sie Image auf dieselbe Weise eine Erweiterungsmethode hinzufügen, wie es Sri Harsha Chilakapati vorschlägt.

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 
} 

Und es wie folgt verwenden:

myImage.toBufferedImage()