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

Hi Chris,

If memory efficiency is not an issue, you can just use the RGB
FlatField by mapping r, g and b to Red, Green and Blue as usual and
the image should look correct visually.

However, if your concern is one of efficiency, things are actually
even worse than you might think because not only does
DataUtility.makeField expand grayscale images to RGB, it also explodes
8-bit and 16-bit values into 32-bit floats, since nearly everything in
VisAD is done with floats or doubles.

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. You should be able to plot the
data using a visad.bom.ImageRendererJ3D more efficiently (i.e.,
without exploding the data values to floats). But math operations will
still cause VisAD to expand the data to floats on the fly, so it's
best to be a bit careful.

See Test73 for an example of usage.

The ImageFlatField logic has not been thoroughly exercised with every
aspect of the VisAD system, so please let me know if you find any
problems with it.

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

There are still many improvements and optimizations that could be done
with ImageFlatField, but I am very busy with other things, so if you
have the time to contribute any improvements, it would be greatly
appreciated.

If ImageFlatField does not suit your purposes, you could write code to
return a regular FlatField by exploding the Image into floating point
values yourself. You'd extract the raw pixel values from your Image
somehow, and convert them to a float[][] array for use with
FlatField.setSamples (use the signature with copy==false to save
memory). One way to do this is with the PixelGrabber class; but no
matter what you need to know certain details about the nature of your
Image object, and how to access its underlying pixel values. Another
solution is to paint it onto a BufferedImage of a specific type as I
outlined above and then obtain the pixel values from the
BufferedImage.getData().getDataBuffer() object.

Java images are fairly nasty and complicated, so please feel free to
ask if you need further clarification on any of this.

-Curtis

On 10/23/07, Christian Schill <christian.schill@xxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi All,
>
>
>
> ...Tavi and I got a question about how to convert a java.awt.image from
> an OGC Web Map Server (WMS) [1] or a Web Coverage Server [2] to a
> FlatField..:
>
> Our problem:
>
> 1. Web map servers render a map as an image from different geospatial
> datasets (raster and vector). We want to request a geotiff image (grey
> values) from the server and interpret this as a digital elevation model
> (or better, as a function (latitude, longitude)---> altitude).
> 2. To connect to the service, we use vividsolution's JUMP library [3],
> [4] - (Java Uniform Mapping Platform)
> We initialize the service with jump like this:
>
> WMService ourWMS = new WMService(URL);
> MapRequest OurReq = ourWMS.createMapRequest();
>
> and finally request the image with
>
> OurReq.getImage();
>
> The return value of OurReq.getImage() is a java.awt.image that we now
> want to convert into a VISAD data object.
>
> We then use DataUtility to create a FlatField:
> imageField = DataUtility.makeField(image);
>
> This imageField
>     System.out.println("FuncType = " + imageField.getType().prettyString());
>     System.out.println("Range dimension in refresh is " +
> imageField.getRangeDimension());
>
> now has a function type (image row, image column) --> (r,g,b)
>
> That means, java.awt.image is a 24bit image rather than the 8bit or 16
> bit grey value tiff we originally requested.
>
> Does someone have a good idea to create an appropriate FlatField, or is
> this even a wrong way to deal with it?
>
> Furthermore -- I think a VISAD wiki could help as a documention and FAQ
> platform -- what do you think?
>
> Thanks in advance for your ideas and suggestions,
>
> Tavi and Chris
>
>
> [1] http://www.opengeospatial.org/standards/wms
> [2] http://www.opengeospatial.org/standards/wcs
> [3] http://www.vividsolutions.com/jump/
> [4] http://www.jump-project.org
>
>
>
> _______________________________________________
> visad mailing list
> visad@xxxxxxxxxxxxxxxx
> For list information, to unsubscribe, visit: 
> http://www.unidata.ucar.edu/mailing_lists/
>


  • 2007 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the visad archives: