web-dev-qa-db-fra.com

Java convertissant une image en image tampon)

Il y a déjà une question comme celle-ci lien sur StackOverflow et la réponse acceptée est "casting":

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

Dans mon programme j'essaie:

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;

Malheureusement, je reçois une erreur d'exécution:

Sun.awt.image.ToolkitImage ne peut pas être converti en Java.awt.image.BufferedImage

De toute évidence, le casting ne fonctionne pas.
La question est la suivante: quelle est (ou existe-t-il) le moyen approprié de convertir Image en BufferedImage?

66
Arek Wilk

À partir d'un moteur de jeu Java :

/**
 * 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;
}
98

Une façon de gérer cela consiste à créer une nouvelle BufferedImage et à indiquer à son objet graphique de dessiner votre image mise à l'échelle dans la nouvelle 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);

Cela devrait faire l'affaire sans casting.

20
salbeira

Si vous récupérez un Sun.awt.image.ToolkitImage, vous pouvez convertir l'image en cela, puis utiliser getBufferedImage () pour obtenir le BufferedImage.

Donc, au lieu de votre dernière ligne de code où vous lancez, vous feriez simplement:

BufferedImage buffered = ((ToolkitImage) image).getBufferedImage();
4
Hermann Hans

Si vous utilisez Kotlin, vous pouvez ajouter une méthode d'extension à Image de la même manière que suggère 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
}

Et utilisez-le comme ceci:

myImage.toBufferedImage()
2
Steven Spungin