2

I want to convert an Image to a BufferedImage. I know the following:

Image tmp;
... //read, scale
BufferedImage buffered = new BufferedImage(SMALL_SIZE, SMALL_SIZE,
                BufferedImage.TYPE_INT_RGB);
buffered.getGraphics().drawImage(tmp, 0, 0, null);

But it's really slow. I need BufferedImage, because I have to get pixel color data. I found a possible way to do it, without drawing:

ToolkitImage ti = (ToolkitImage) tmp;
BufferedImage buffered = tmp.getBufferedImage();

But it always returns null. Can anyone offer a solution for this?

EDIT: The bigger task (source of this problem) is here: Scale a BufferedImage the fastest and easiest way

Community
  • 1
  • 1
tamas.pflanzner
  • 325
  • 1
  • 6
  • 11
  • For better help sooner, post an [SSCCE](http://sscce.org/). Also, noting that J2SE has no `ToolkitImage`, are you using Android? – Andrew Thompson May 13 '13 at 13:22
  • @AndrewThompson I edited the question, is it better now? The ToolkitImage is in the sun.awt.image.ToolkitImage. – tamas.pflanzner May 13 '13 at 13:40
  • Don't use classes in the `sun` hierarchy of packages! They may not be in the next Oracle JRE, and probably would not be in the JRE of another manufacturer. – Andrew Thompson May 13 '13 at 13:48
  • It would be great to not use this class at all, but I need a solution to convert the Image to BufferedImage as fast as possible. – tamas.pflanzner May 13 '13 at 16:05

4 Answers4

3

Had the same conversion issue with ToolkitImage to BufferedImage.

Graphics2D g2d = buffImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();

-- was drawing nothing to the buffered image, and image.getBufferedImage(); was null

That is what have helped, using the ImageIcon to init some internall stuff in the original Image.

ToolkitImage toolkitImage = (ToolkitImage) Toolkit.getDefaultToolkit().createImage("image.jpg");

Image temporary = new ImageIcon(toolkitImage).getImage();

BufferedImage buffImage = new BufferedImage(toolkitImage.getWidth(), toolkitImage.getHeight(),
        BufferedImage.TYPE_INT_ARGB);

Graphics2D g2d = buffImage.createGraphics();
g2d.drawImage(temporary, 0, 0, null);
g2d.dispose();

After that buffImage contained the image from toolkitImage.

Artem
  • 66
  • 6
2

Had the same issue. For some weird reasons, I managed to get the image via the ImageIcon. So I loaded the byteArray(imageDate) into the ImageIcon and then read the image off the ImageIcon and it worked fine.

Ratshiḓaho Wayne
  • 743
  • 1
  • 5
  • 23
2

If you query the getHeight() or getWidth() methods on the ToolkitImage you will trigger the generation of the internal BufferedImage. So your code would become:

ToolkitImage ti = (ToolkitImage) tmp;
ti.getWidth();
BufferedImage buffered = ti.getBufferedImage();

I doubt this will be any faster than the drawImage() method you described, but is worth a try.

notedible
  • 983
  • 7
  • 9
1

I don't know a faster way to convert Image to BufferedImage using only JDK. If you are unrestricted, maybe you could write a faster solution in C or C++ and access via JNI. I bet ImageMagick has some crazy fast, optimized routines. Edit: This answer has a good suggestion: https://stackoverflow.com/a/7726679/257299

A different strategy would be to avoid calling Image Toolkit.getImage(URL). This requires a conversion to BufferedImage. Instead, try: BufferedImage ImageIO.read(File)

About why BufferedImage ToolkitImage.getBufferedImage() always returns null:

  1. ToolkitImage is part of the sun package which is not considered part of the JDK public API. Avoid using directly. I know: If you code Swing, you will see people breaking this rule often, since Sun made such heavy use of non-public classes in Swing. (SwingUtilities does all kind of sneaky things with package-private methods and classes.)
  2. Method getBufferedImage() returns a non-null reference if the buffered image has been generated internally by TookitImage. Read that last sentence again. The important term is generated. This method is not "free" and surely incurs heavy processing cost to convert internal data to BufferedImage. Most often (99%) the BufferedImage has not been generated, so the return value is null. JDK Source Reference
Community
  • 1
  • 1
kevinarpe
  • 20,319
  • 26
  • 127
  • 154