Saving large images - Raster problem
I already asked a Question how to save large images and I think I'm on the right track but I still need some advice.
I have an Image 12000 x 12000 and I need to save it as .png
BufferedImage can't be used.
I was already advised to use the RenderedImage interface but somehow I can't get the desired result. ( I haven't worked with rasters yet so probably I got something wrong )
Code for the saving image method:
public static void SavePanel() {
PanelImage IMAGE = new PanelImage(panel);
try {
ImageIO.write(IMAGE, "png"开发者_JS百科, new File(ProjectNameTxt.getText() + ".png"));
} catch (IOException e) {
}
}
And 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 the ImageIO requests one line of pixels at a time ( 12000 x 1 ). This method is working but I still need the whole image in the BufferedImage. I have to increase the size of the BImage each time ImageIO calls the method, otherwise I get " Coordinate out of bounds! " exeption
Thanks
This PNGJ library can be useful to read/write huge images, because it does it sequentially, it only keeps a line in memory at a time. (I wrote it myself a while ago, because I had a similar need)
I just hacked an minimal working example for a ComponentImage
, which takes an arbitrary JComponent
and can be passed to ImageIO
for writing. 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;
}
}
精彩评论