Слияние небольших изображений в одно без выделения полного изображения в памяти - PullRequest
1 голос
/ 04 марта 2011

Мне нужно сделать сценарий параллельной обработки изображений в Java, идея состоит в том, чтобы разделить изображения на плитки любого размера, обработать их и собрать окончательное изображение.

На данный момент я создал функцию:

public static BufferedImage readImg (String path, int startx, int starty, int w, int h)

, который возвращает область изображения как BufferedImage, затем я обработаю его и хочу разместить эту область в правильном положении конечного изображения.

Итак, я попытался создать функцию writeImg, которая использует метод replacePixels для записи только в правильном положении без загрузки всего изображения в память:

public static void writeImg (String path, int startx, int starty, BufferedImage image){
    File output = new File(path);
    ImageOutputStream ios = null;
    try {
        ios = ImageIO.createImageOutputStream(output);
    } catch (IOException e){
        e.printStackTrace();
    }
    Iterator iter = ImageIO.getImageWritersByFormatName("JPEG");
    ImageWriter writer = (ImageWriter)iter.next();
    writer.setOutput(ios);

    try{
        if(writer.canReplacePixels(0)){
            System.out.println("True");
        }else{
            System.out.println("False");
        }
    }catch (IOException e) {
        e.printStackTrace();
    }

    ImageWriteParam param = writer.getDefaultWriteParam();
    Point destinationOffset = new Point(startx,starty);
    param.setDestinationOffset(destinationOffset);
    try {
        writer.replacePixels(image, param);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Проблема в том, что canReplacePixels всегда устанавливается в значение false, и я понятия не имею, что я должен использовать для этого.

Изображения могут быть очень большими, поэтому невозможно загрузить все изображение в память, так как это вызовет исключение OutOfMemory.

1 Ответ

2 голосов
/ 04 марта 2011

Пока вы в порядке с 24-битным PNG-файлом в качестве вывода, у меня есть рабочее решение для вас (под лицензией GPL):

Класс PngXxlWriter позволяет записывать PNG-файлы «построчно». Это означает, что вы можете написать изображение размером 10000x10000 (ширина * высота) пикселей, например, в строках. 256 пикселей (10000 * 256).

Обычно это уменьшает использование памяти до уровня, который практически равен.

Все необходимые классы можно найти здесь:

PngXxlWriter - основной класс. Вызвав его метод writeTileLine, вы можете добавить новую строку к выходному изображению.

https://trekbuddyatlasc.svn.sourceforge.net/svnroot/trekbuddyatlasc/trunk/MOBAC/src/main/java/mobac/utilities/imageio

...