Skip to main content

best approach for huge image

3 replies [Last post]
shikida
Offline
Joined: 2007-02-15

hi, I am trying to generate a huge (15,000 x 20,000 pixels) offline image

This image is draw into a JComponent object, which contains different parts of the component, and these parts are put together using swing's pack() method. After that, the JComponent content is copied to a BufferedImage and then splitted into several smaller images.

I am quite sure this is not the most efficient way to do this :-) but since I am working on a 3rd party code, it can take some time to re-write the components draw() methods.

The obvious problem is memory. Working in a 32-bit environment, I can't address more than 2GB for the jvm heap, so I am running out of memory easily.

Here goes a snippet. What approach do you guys suggest? Thanks in advance.

public static BufferedImage createImage(JComponent component, Rectangle region) throws IOException{
boolean opaqueValue = component.isOpaque();
component.setOpaque( true );
logger.debug("image "+region.width+","+region.height);
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setClip( region );
component.paint( g2d );
g2d.dispose();
logger.debug("dispose");
component.setOpaque( opaqueValue );
return image;
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Roman Kennke

Hello,

> hi, I am trying to generate a huge (15,000 x 20,000 pixels) offline image
>
> This image is draw into a JComponent object, which contains different parts of the component, and these parts are put together using swing's pack() method. After that, the JComponent content is copied to a BufferedImage and then splitted into several smaller images.
>
> I am quite sure this is not the most efficient way to do this :-) but since I am working on a 3rd party code, it can take some time to re-write the components draw() methods.
>
> The obvious problem is memory. Working in a 32-bit environment, I can't address more than 2GB for the jvm heap, so I am running out of memory easily.
>
> Here goes a snippet. What approach do you guys suggest? Thanks in advance.
>
> public static BufferedImage createImage(JComponent component, Rectangle region) throws IOException{
> boolean opaqueValue = component.isOpaque();
> component.setOpaque( true );
> logger.debug("image "+region.width+","+region.height);
> BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
> Graphics2D g2d = image.createGraphics();
> g2d.setClip( region );
> component.paint( g2d );
> g2d.dispose();
> logger.debug("dispose");
> component.setOpaque( opaqueValue );
> return image;
> }

I am not sure if I understood the problem correctly. Let me get this
straight: You have a component A. Multiple parts of this component
should be drawn into component B. In order to achieve this, you create
BufferedImages and let the component A paint regions of itself into the
images. Then these images are themselves painted into the component B.
Is this correct?

Assuming this is what you want to do, you could let the component A
paint directly into component B, without creating intermediate buffers.
For example, in component A (very much simplified):

public void paint(Graphics g) {
Rectangle region = ...;
g.setClip(region);
componentB.paint(g);
}

You would probably call componentB.paint() more than once with different
regions, but this should get you an idea.

Generally I would avoid creating 300MB buffered images for obvious
reasons. Maybe I misunderstood something, in which case it would be
helpful to have more information what component should draw what.

Regards, Roman

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

shikida
Offline
Joined: 2007-02-15

I am moving this thread to http://forums.java.net/jive/thread.jspa?threadID=23403

thanks

roman_kennke
Offline
Joined: 2007-02-16

Hello,

> hi, I am trying to generate a huge (15,000 x 20,000 pixels) offline image
>
> This image is draw into a JComponent object, which contains different parts of the component, and these parts are put together using swing's pack() method. After that, the JComponent content is copied to a BufferedImage and then splitted into several smaller images.
>
> I am quite sure this is not the most efficient way to do this :-) but since I am working on a 3rd party code, it can take some time to re-write the components draw() methods.
>
> The obvious problem is memory. Working in a 32-bit environment, I can't address more than 2GB for the jvm heap, so I am running out of memory easily.
>
> Here goes a snippet. What approach do you guys suggest? Thanks in advance.
>
> public static BufferedImage createImage(JComponent component, Rectangle region) throws IOException{
> boolean opaqueValue = component.isOpaque();
> component.setOpaque( true );
> logger.debug("image "+region.width+","+region.height);
> BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
> Graphics2D g2d = image.createGraphics();
> g2d.setClip( region );
> component.paint( g2d );
> g2d.dispose();
> logger.debug("dispose");
> component.setOpaque( opaqueValue );
> return image;
> }

I am not sure if I understood the problem correctly. Let me get this
straight: You have a component A. Multiple parts of this component
should be drawn into component B. In order to achieve this, you create
BufferedImages and let the component A paint regions of itself into the
images. Then these images are themselves painted into the component B.
Is this correct?

Assuming this is what you want to do, you could let the component A
paint directly into component B, without creating intermediate buffers.
For example, in component A (very much simplified):

public void paint(Graphics g) {
Rectangle region = ...;
g.setClip(region);
componentB.paint(g);
}

You would probably call componentB.paint() more than once with different
regions, but this should get you an idea.

Generally I would avoid creating 300MB buffered images for obvious
reasons. Maybe I misunderstood something, in which case it would be
helpful to have more information what component should draw what.

Regards, Roman