Re: [visad] Convert java.awt.image from Web Map Server to a FlatField

Hi Curtis, hi all,

perhaps you remember the problem we discussed in October '07 (yew, time is 
fleeting - how to read
images from a WMS into a flatfield) -- finally we found the time to use your 
suggestions and
everything worked fine. Thanks a lot. Just one small addition to your 
"makeBuffered()"-method (see
below).

[..]
> I have put some work into an alternative type of FlatField for images
> that is more efficient called ImageFlatField. You could give it a try:
> just construct a new ImageFlatField object around your
> java.awt.image.BufferedImage object and use the resulting object the
> same as you would a normal FlatField. 
[..]
> See Test73 for an example of usage.
[..]
> If your java.awt.Image is not a BufferedImage, you can convert it into
> one with code like this:
> 
>   public static BufferedImage makeBuffered(Image image) {
>     if (image instanceof BufferedImage) return (BufferedImage) image;
>     BufferedImage img = new BufferedImage(image.getWidth(this),
>       image.getHeight(this), BufferedImage.TYPE_INT_RGB);
>       // or TYPE_BYTE_GRAY or whatever is appropriate
>     Graphics g = img.getGraphics();
>     g.drawImage(image, 0, 0, this);
>     g.dispose();
>     return img;
> }


The parameters of the drawImage() method are
drawImage(Image img, int x, int y, ImageObserver observer)

with ImageObserver being an interface that is implemented by the class 
Component.
So one can use "this" if the call to drawImage() is within a class that is 
derived from Component.
Otherwise, if your class isn't derived from Component one can call drawImage() 
with null.

g.drawImage() returns TRUE if pixel values don't change any more (image 
completely loaded) and
false otherwise. If you retrieve images from a server it might be useful to 
wait until the image
has been read completely with 

    while (!g.drawImage(image, 0, 0, null));

before disposing with g.dispose().
(at least this did the trick for us and perhaps this might be useful for 
others). So our method
finally is
------------------------------------------------------
public BufferedImage makeBuffered(Image image, int width, int height) {
    if (image instanceof BufferedImage) return (BufferedImage) image;
    BufferedImage img = new BufferedImage(width, height, 
bufferedImage.TYPE_BYTE_GRAY);
      // or TYPE_BYTE_GRAY or whatever is appropriate
    Graphics g = img.getGraphics();
    while (!g.drawImage(image, 0, 0, null));
    g.dispose();
    return img;
}
------------------------------------------------------

I'm sure one can do some useful extensions (e.g. if you are using an 
ImageObserver I think 
int checkImage(Image, ImageObserver)
and
boolean prepareImage(Image, ImageObserver)

might be worth looking at, also at a timeout in the while loop (of course), but 
at the moment this
is ok for us.

Thanks again and greetings!

Chris