4

I am wondering is there a way to convert Image to BufferedImage without code like a

new BufferedImage(...)

because every new init makes app run slower , moreover, if it is in paint() method :(

Please advise the most optimal conversion way.

Thanks

user592704
  • 3,674
  • 11
  • 70
  • 107

3 Answers3

6

No. Not unless the original Image happens to be a BufferedImage already. Then you can just do a cast:

BufferedImage bufImg = null;
if (origImage instanceof BufferedImage) {
    bufImg = (BufferedImage) origImage;
else {
    bugImg = new BufferedImage(...);
    // proper initialization
}

If it's not a BufferedImage it may very well be for instance a VolatileImage (the other concrete subclass in the API).

From the docs on volatile image:

VolatileImage is an image which can lose its contents at any time due to circumstances beyond the control of the application (e.g., situations caused by the operating system or by other applications).

As you may understand, such image can not provide the same interface as a BufferedImage, thus the only way to get hold of a BufferedImage is to create one, and draw the original image on top of it.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • I mean this image as java.awt.Image :) Oh... So I need to figure out something here then because repaint with new BufferedImage is too slow :( Is there a way to walk it around? – user592704 Apr 27 '11 at 20:27
  • @user592704: java.awt.Image is an abstract class, so while yes, your image is an Image object, it is also an instance of one of Image's concrete children as aioobe well states above. – Hovercraft Full Of Eels Apr 27 '11 at 21:30
  • But what about VolatileImage effect? – user592704 Apr 27 '11 at 23:56
6

because every new init makes app run slower

Cache one BufferedImage, then only create a new image if the required size changes. Otherwise clear the Graphics object of the current instance and do whatever new drawing is needed.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • +1 : if you're creating new BufferedImages all the time in a normal Java GUI app then you're almost certainly doing something very sub-optimal – mikera Apr 27 '11 at 20:56
  • Emm... I have to make new init each BufferedImage resizing? – user592704 Apr 27 '11 at 21:02
  • So each time the scale changes BufferedImage must be reinited? – user592704 Apr 27 '11 at 21:08
  • What 'scale'? Note that it is quite easy to scale (crop, rotate etc.) an image at the moment it is drawn. – Andrew Thompson Apr 27 '11 at 21:22
  • Emm... the JLabel scale :) I keep ImageIcons with this component. – user592704 Apr 27 '11 at 21:24
  • 1
    Since this is the first mention of either `JLabel` or `ImageIcon` in this thread, I think it is time to add.. For better help sooner, post an [SSCCE](http://pscode.org/sscce.html). For an SSCCE that needs images, either generate them in code, or hot-link to some existing images on the net. Here are some example [images you can link to](http://pscode.org/media/#image). – Andrew Thompson Apr 27 '11 at 21:28
  • I just wondering is there a way to draw BufferedImage to JLabel with the paint method? I couldn't find any examples :( – user592704 Apr 27 '11 at 21:31
  • +1 I've elaborated on this important technique in an adjacent answer. – trashgod Apr 27 '11 at 22:21
2

Is there a way to draw a BufferedImage to JLabel with the paint() method?

One convenient approach is to implement the Icon interface. In this example, Histogram simply draws itself when the label is told to repaint().

If the source of the image requires a time-consuming operation such as scaling, pre-render the image as shown in the static factory, GradientImage.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thank you. It is much useful :) But I use getImage() method just to get Image from ImageIcon so there is no problem to get it. So the question is not in JLabel as it is but how to convert Image to BufferedImage – user592704 Apr 27 '11 at 23:53
  • But since now I am not so pretty sure I should to... But maybe I should use BufferedImage right from the beginning not to convert something at all? – user592704 Apr 27 '11 at 23:55
  • 1
    One guiding principle is to use the most general type that is consistent with the intended use. What you are doing to the `BufferedImage` when painting that couldn't be done ahead of time when loading? – trashgod Apr 28 '11 at 00:57
  • I was trying to test alpha composite :) – user592704 Apr 28 '11 at 02:22
  • Emm... This is something like this http://download.oracle.com/javase/tutorial/2d/images/examples/SeeThroughImageApplet.java but ImageIcon contains Image so that is a little problem :X – user592704 Apr 28 '11 at 02:23
  • 1
    Ah, you might like to see this [`AlphaComposite`](http://sites.google.com/site/drjohnbmatthews/composite) utility, which also implements `Icon`. – trashgod Apr 28 '11 at 02:52
  • separate and conquer - there's not really a reason (IMO) to let Histogram subclass a JLabel to implement an Icon just painting itself. Extract the HistogramIcon and re-use in every icon-aware component :-) – kleopatra Apr 28 '11 at 15:26
  • @kleopatra: One convenience is the very flexible text positioning afforded by `JLabel`. @user592704: In general, kleopatra's point is very well-taken; this [example](http://stackoverflow.com/questions/3066590/gui-problem-after-rewriting-to-mvc/3072979#3072979) shows a `ColorIcon` separate from the button that uses it. – trashgod Apr 28 '11 at 16:42
  • 1
    Thank you. It is very useful :) I am going to check all advices – user592704 Apr 30 '11 at 01:15