问题
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
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
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:
ToolkitImageis part of thesunpackage 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. (SwingUtilitiesdoes all kind of sneaky things with package-private methods and classes.)- Method
getBufferedImage()returns a non-nullreference if the buffered image has been generated internally byTookitImage. 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 toBufferedImage. Most often (99%) theBufferedImagehas not been generated, so the return value isnull. JDK Source Reference
来源:https://stackoverflow.com/questions/16522965/why-does-toolkitimage-getbufferedimage-return-a-null