MapContext to JPEG or PNG image?

8 messages Options
Embed this post
Permalink
Oliver Gottwald

MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink

Hi,

I was wondering if anyone has taken a MapContext and did a write to a JPEG file?
I've been messing with this but have been unable to get further then a white image.

I think the example may work if I can get the JMapPane to convert correctly for the MapContext
currently w and h are being forced for the line:
BufferedImage(pane.getBounds().width, pane.getBounds().height, BufferedImage.BITMASK);

to 400, 400 because they are 0.

Any input would be greatly appreciated.


public void saveImage(String filePath, MapContext map_context){
   
    GTRenderer gt_renderer = (GTRenderer)new StreamingRenderer();
    JMapPane pane = new JMapPane(gt_renderer, map_context);

    System.out.println("Start: saveImage(" + filePath + ")");
   
   
    //BufferedImage(pane.getBounds().width, pane.getBounds().height, BufferedImage.BITMASK);
    BufferedImage bufferedImage  = new BufferedImage(400, 400, BufferedImage.BITMASK);
    Graphics2D g2 = bufferedImage.createGraphics();
         
    pane.paint(g2);
   
    try {
        ImageIO.write(bufferedImage, "png", new File(filePath));
    } catch (Exception e) {
        e.printStackTrace();
    }        
    g2.dispose();
   
    System.out.println("End: saveImage(" + filePath + ")");
}



------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
mbedward

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
Hi Oliver,

Thanks for the question. It's prompted me to look at the JMapPane code
and see how to make it easier to save an image. In GeoTools 2.6.0 you
can get the map pane's cached image with mapPane.getBaseImage() but
the image is configured for saving easily to JPG.

I'll make some changes to the code and put together a new example.
Meanwhile, here is a method that should work...

Rectangle paintArea = mapPane.getVisibleRect();

BufferedImage image = new BufferedImage(
        paintArea.width, paintArea.height,
        BufferedImage.TYPE_INT_RGB);

Graphics2D gr = image.createGraphics();

gr.setComposite(AlphaComposite.Src);
gr.setPaint(Color.WHITE);
gr.fill(paintArea);

mapPane.getRenderer().paint(gr,
        mapPane.getVisibleRect(), mapPane.getDisplayArea(),
        mapPane.getWorldToScreenTransform());

File fileToSave = ...

try {
        ImageIO.write(image, "jpeg", fileToSave);
} catch (IOException ex) {
        // bummer...
} finally {
        gr.dispose();
}

Hope that helps.

Michael

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
Oliver Gottwald

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
I plugged in the changes from your example but I'm getting a runtime exception:

I think my MapContext is not converting to a JMapPane correctly
The following is my method, then the exception:

Any help on this would be greatly appreciated.

public void saveImage(MapContext map){
    GTRenderer gt_renderer = (GTRenderer)new StreamingRenderer();
    JMapPane mapPane = new JMapPane(gt_renderer, map);
   
    Rectangle paintArea = mapPane.getVisibleRect();
   
    BufferedImage image = new BufferedImage(
               paintArea.width, paintArea.height,
               BufferedImage.TYPE_INT_RGB);

        Graphics2D gr = image.createGraphics();

        gr.setComposite(AlphaComposite.Src);
        gr.setPaint(Color.WHITE);
        gr.fill(paintArea);

        mapPane.getRenderer().paint(gr,
               mapPane.getVisibleRect(), mapPane.getDisplayArea(),
               mapPane.getWorldToScreenTransform());

        File fileToSave = new File("/test.jpg");

        try {
               ImageIO.write(image, "jpeg", fileToSave);
        } catch (IOException ex) {
               // bummer...
        } finally {
               gr.dispose();
        }
       
}

The following is the error I'm getting:
Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
    at java.awt.image.BufferedImage.<init>(Unknown Source)
    at org.geotools.demo.DisplayTreeMap.saveImage(DisplayTreeMap.java:409)
    at org.geotools.demo.DisplayTreeMap.main(DisplayTreeMap.java:116)

If I just force the paintArea.width and paintArea.height to 400, 400 i get the following exception:
Exception in thread "main" java.lang.NullPointerException: renderer passed null arguments
    at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:584)
    at org.geotools.demo.DisplayTreeMap.saveImage(DisplayTreeMap.java:420)
    at org.geotools.demo.DisplayTreeMap.main(DisplayTreeMap.java:116)


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
mbedward

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
Hi Oliver,

It looks like you have not displayed the map pane prior to calling the
renderer paint method so its visible rectangle has width = height = 0.

If you are just interested in drawing to an image, rather than saving
what is on screen in the map pane, you don't need the map pane in that
code at all. Just work directly with the renderer and use the paint
method that does not have the world to screen transform arg:

MapContext map = ...

// ... add layers to map context ...

GTRenderer renderer = new StreamingRenderer();
renderer.setContext( map );

Rectangle imageSize = ...
Graphics2D gr = ...

renderer.paint(gr, imageSize, map.getLayerBounds());

// .. then save image ...

Hope this helps. Please let me know how you go.

Michael

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
Oliver Gottwald

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
Michael and Jody,

Thank you for the solution to getting a JPEG from the MapContext!

1)  Towards the bottom of this post is my working solution/method.

2)  iText JPEG integration (for the most part):

To get the image into Itext all that has to happen (from mem) is pretty much the following:

imports:
import com.lowagie.text.*;

code snipped:
try{
Document document = new Document();
FileOutputStream fos = new FileOutputStream (propertiesUO.getProperty("/test.pdf");
PdfWriter writer = PdfWriter.getInstance(document, fos);
document.open();
Image hjpg = Image.getInstance("/test.jpg");
document.add(hjpg);

document.close();
fos.close();
} catch(Exception e){
     //bummer :-)
}

3)  QUESTION:

One thing I was wondering is there a way to get the width and height for the image so that the graphic is not distorted.  The 600,600 in my Rectangle.
    Rectangle imageSize = new Rectangle(600,600);
I was looking at the following:
try{
        ReferencedEnvelope r=map.getLayerBounds();
        System.out.println("MaxX="+r.getMaxX()+
                                   " MaxY="+r.getMaxY()+
                                   " MinX="+r.getMinX()+
                                   " MinY="+r.getMinY());
        System.out.println("height="+r.getHeight()+" width="+r.getWidth());
}catch(Exception e){
        //bummer :-)
}
       
With values:
MaxX=50.0 MaxY=30.0 MinX=15.0 MinY=15.0
height=15.0 width=35.0

Is there a way to convert any of these values to the width and height of the Rectanble(600,600) above so that there is no distortion?

4)  working example (MapContext to jpeg):

public void saveImage(MapContext map, String file){

    GTRenderer renderer = new StreamingRenderer();
    renderer.setContext( map );
   
    Rectangle imageSize = new Rectangle(600,600);
   
    BufferedImage image = new BufferedImage(imageSize.width, imageSize.height, BufferedImage.TYPE_INT_RGB);
    Graphics2D gr = image.createGraphics();
    gr.setPaint(Color.WHITE);
    gr.fill(imageSize);  //otherwise black background - which throws of transparency of color
    try {
        renderer.paint(gr, imageSize, map.getAreaOfInterest());
        File fileToSave = new File(file);
        ImageIO.write(image, "jpeg", fileToSave);
    }catch(IOException e){
       
    }
   
}


Thanks Again,
Oliver


-----Original Message-----
From: "Michael Bedward" <[hidden email]>
Sent: Wednesday, October 28, 2009 11:10pm
To: "Oliver Gottwald" <[hidden email]>
Cc: [hidden email]
Subject: Re: [Geotools-gt2-users] MapContext to JPEG or PNG image?

Hi Oliver,

It looks like you have not displayed the map pane prior to calling the
renderer paint method so its visible rectangle has width = height = 0.

If you are just interested in drawing to an image, rather than saving
what is on screen in the map pane, you don't need the map pane in that
code at all. Just work directly with the renderer and use the paint
method that does not have the world to screen transform arg:

MapContext map = ...

// ... add layers to map context ...

GTRenderer renderer = new StreamingRenderer();
renderer.setContext( map );

Rectangle imageSize = ...
Graphics2D gr = ...

renderer.paint(gr, imageSize, map.getLayerBounds());

// .. then save image ...

Hope this helps. Please let me know how you go.

Michael

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
mbedward

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
Hi Oliver

> Thank you for the solution to getting a JPEG from the MapContext!

You're welcome. Always nice to hear the sound of a satisfied customer :-)

> 2)  iText JPEG integration (for the most part):

Many thanks - that's very useful.

> One thing I was wondering is there a way to get the width and height for the
> image so that the graphic is not distorted.

I'm presently coding a dialog for the swing module (called
JMapImageDialog at the moment) to help do that. Its calculations are
simple...

ReferencedEnvelope mapBounds = ...
double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);

int imageWidth = ...
Rectangle imageBounds = new Rectangle(
        0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));

Note: JMapImageDialog will also check for axis swapping if a CRS is
defined which I haven't shown in the above code.  Also, it will let
you set the image size indirectly by specifying the output map scale.

Thanks again for posting your working code to the list.

Michael

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
Oliver Gottwald

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
In reply to this post by Oliver Gottwald

Here is the complete MapContext to image method example with proper image sizing.

public void saveImage(MapContext map, String file){

    GTRenderer renderer = new StreamingRenderer();
    renderer.setContext( map );
   
    Rectangle imageBounds=null;
    try{
        ReferencedEnvelope mapBounds=map.getLayerBounds();
        double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);
        int imageWidth = 600;
        imageBounds = new Rectangle(
                0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));
    }catch(Exception e){
       
    }
   
    //Rectangle imageSize = new Rectangle(600,600);
   
    BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height,      BufferedImage.TYPE_INT_RGB); //darker red fill
    Graphics2D gr = image.createGraphics();
    gr.setPaint(Color.WHITE);
    gr.fill(imageBounds);
   
    try {
        renderer.paint(gr, imageBounds, map.getAreaOfInterest());
       
        File fileToSave = new File(file);
        ImageIO.write(image, "jpeg", fileToSave);
    }catch(IOException e){
       
    }
   
}


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
mbedward

Re: MapContext to JPEG or PNG image?

Reply Threaded More More options
Print post
Permalink
Thanks for posting your code Oliver !

Michael

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Geotools-gt2-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users