Сохранение больших изображений - проблема растров - PullRequest
4 голосов
/ 15 июля 2011

Я уже задавал вопрос, как сохранить большие изображения, и я думаю, что я на правильном пути, но мне все еще нужен совет.

У меня есть изображение 12000 x 12000, и мне нужно сохранить его как .png

BufferedImage не может быть использовано.

Мне уже советовали использовать интерфейс RenderedImage, но почему-то я не могу получить желаемый результат. (Я еще не работал с растрами, поэтому, возможно, я что-то не так понял)

Код для метода сохранения изображения:

   public static void SavePanel() {

    PanelImage IMAGE = new PanelImage(panel);

    try {
        ImageIO.write(IMAGE, "png", new File(ProjectNameTxt.getText() +  ".png"));
    } catch (IOException e) {
    }

   }

И код для класса PanelImage:

 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
 }

Я заметил, что ImageIO запрашивает одну строку пикселей за раз (12000 x 1). Этот метод работает, но мне все еще нужно все изображение в BufferedImage. Я должен увеличивать размер BImage каждый раз, когда ImageIO вызывает метод, в противном случае я получаю исключение «Координировать вне границ!»

Спасибо

Ответы [ 2 ]

3 голосов
/ 17 июля 2011

Эта PNGJ библиотека может быть полезна для чтения / записи огромных изображений, потому что она делает это последовательно, она только сохраняет строку в памяти за один раз. (Я сам написал это недавно, потому что у меня была похожая потребность)

2 голосов
/ 18 июля 2011

Я только что взломал минимальный рабочий пример для ComponentImage, который принимает произвольный JComponent и может быть передан ImageIO для записи.Для краткости сюда включены только «интересные» детали:

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;

    }
}
...