Java converting Image to BufferedImage

JavaImageCastingBufferedimage

Java Problem Overview


There is already question like this link on StackOverflow and the accepted answer is "casting":

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

In my program I try:

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 I get run time error:

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

Obviously casting does not work.
Question is: What is (or is there) the proper way of converting Image to BufferedImage?

Java Solutions


Solution 1 - Java

From a 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;
}

Solution 2 - Java

One way to handle this is to create a new BufferedImage, and tell it's graphics object to draw your scaled image into the new 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);

That should do the trick without casting.

Solution 3 - Java

If you use Kotlin, you can add an extension method to Image in the same manner Sri Harsha Chilakapati suggests.

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
}

And use it like this:

myImage.toBufferedImage()

Solution 4 - Java

If you are getting back a sun.awt.image.ToolkitImage, you can cast the Image to that, and then use getBufferedImage() to get the BufferedImage.

So instead of your last line of code where you are casting you would just do:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArek WilkView Question on Stackoverflow
Solution 1 - JavaSri Harsha ChilakapatiView Answer on Stackoverflow
Solution 2 - JavasalbeiraView Answer on Stackoverflow
Solution 3 - JavaSteven SpunginView Answer on Stackoverflow
Solution 4 - JavaHermann HansView Answer on Stackoverflow