Saving Large Images - Raster Problem

I already asked how to save large images, and I think I'm on the right track, but I still need some advice.

I have a 12000 x 12000 image and I need to save it as .png

BufferedImage cannot be used.

I have already been recommended to use the RenderedImage interface, but for some reason I can not get the desired result. (I have not worked with rasters yet, so I probably have something wrong)

Code for the method of saving images:

public static void SavePanel() { PanelImage IMAGE = new PanelImage(panel); try { ImageIO.write(IMAGE, "png", new File(ProjectNameTxt.getText() + ".png")); } catch (IOException e) { } } 

And the code for the PanelImage class:

  public static class PanelImage implements RenderedImage { // some variables here public PanelImage(JImagePanel panel) { this.panel = panel; } public Raster getData(Rectangle rect) { sizex = (int) rect.getWidth(); sizey += (int) rect.getHeight(); image = null; image = new BufferedImage( (int) sizex, (int) sizey, BufferedImage.TYPE_INT_RGB); g2 = image.createGraphics(); panel.paintComponent(g2); return image.getData(); } // rest of the implemented methods - no problems here } 

I noticed that ImageIO requests one row of pixels at a time (12000 x 1). This method works, but I still need the whole image in BufferedImage. I have to increase the size of BImage every time ImageIO calls a method, otherwise I get "Coordination Outside!" Exeption

thanks

+3
source share
3 answers

This PNGJ library can be useful for reading / writing huge images, since it is executed sequentially, it only stores a line in memory on time. (I wrote this myself a while ago because I had a similar need)

+3
source

I just hacked a minimal working example for ComponentImage , which accepts an arbitrary JComponent and can be passed to ImageIO for recording. For brevity, only the โ€œinterestingโ€ parts are included here:

 public final class ComponentImage implements RenderedImage { private final JComponent comp; private final ColorModel colorModel; private final SampleModel sampleModel; public ComponentImage(JComponent comp) { this.comp = comp; this.colorModel = comp.getColorModel(); this.sampleModel = this.colorModel.createCompatibleWritableRaster(1, 1). getSampleModel(); } @Override public ColorModel getColorModel() { return this.comp.getColorModel(); } @Override public SampleModel getSampleModel() { return this.sampleModel; } @Override public Raster getData(Rectangle rect) { final WritableRaster raster = this.colorModel. createCompatibleWritableRaster(rect.width, rect.height); final Raster result = raster. createChild(0, 0, rect.width, rect.height, rect.x, rect.y, null); final BufferedImage img = new BufferedImage( colorModel, raster, true, null); final Graphics2D g2d = img.createGraphics(); g2d.translate(-rect.x, -rect.y); this.comp.paintAll(g2d); g2d.dispose(); return result; } } 
+2
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 saves the image on the hard drive, not using RAM.

Create the BigBufferedImage file from the image file:

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

Create an empty BigBufferedImage:

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

Display part of image:

  part = image.getSubimage(x, y, width, height); 

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

0
source

All Articles