Memory issue while maintaining large BufferedImage value

I have a problem saving large images (e.g. 12,000 x 9,000).

I am developing graphic editing software (something like simple Photoshop) and the User should obviously be able to save the image.

Suppose I would like to save the image as .png. Should JAVA always use BufferedImage to save drawn materials?

I know the equation for the image size: Xsize * Ysize * 4 (red, green, blue, alpha) Thus, in this case we get more than 400 MB.

I know that I can save the image in parts (tiles), but the user will still have to combine them.

Is there any other way to save such a large image without using BufferedImage?

Code for saving the image:

public static void SavePanel() { BufferedImage image = null; image = new BufferedImage( (int) (Main.scale * sizeX ), (int) (Main.scale * sizeY ), BufferedImage.TYPE_INT_RGB); g2 = image.createGraphics(); panel.paint(g2); try { ImageIO.write(image, "png", new File(FactoryDialog.ProjectNameTxt.getText() + ".png")); } catch (IOException e) { } } 

Thank you in advance!

+6
source share
3 answers

ImageIO.write(..) methods accept a RenderedImage , not just a BufferedImage . I successfully used this fact some time ago to write out really large images. Typically, recording implementations record an image sequentially and request a RenderedImage only for the fragments that they currently need.

From a look at your code, I think it should be possible to hack the RenderedImage implementation, which takes your panel constructor in it and can be passed to ImageIO for writing. During the process, ImageIO requests data from your image. You can then use the panel to create the requested snippets (content Raster ) on the fly. Thus, the entire image should not be stored in memory at any point. The starting point for this approach is

 public class PanelImage implements RenderedImage { private final Panel panel; public PanelImage(Panel panel) { this.panel = panel; } /* implement all the missing methods, don't be afraid, most are trivial */ } 

Obviously, you should also check to see if your panel the same problem as BufferedImage . Depending on the nature of your application, you will have to keep the image in memory at least once (modulo using tiles). But in this way, you can at least avoid duplication.

+5
source

Instead, a proprietary image editor such as image magic is used.

0
source

You can use BigBufferedImage instead of BufferedImage. It can handle much larger images, which allows you to limit memory. The trick is that its buffer is replaced by a file implementation of DataBuffer. It stores the decoded raw image in files on the hard drive.

Create BigBufferedImage:

  BigBufferedImage image = BigBufferedImage.create( tempDir, width, height, TYPE_INT_RGB); 

Create the BigBufferedImage file from the image file:

  BigBufferedImage image = BigBufferedImage.create( imageFile, tempDir, TYPE_INT_RGB); 

For more information on large image processing, read this article .

0
source