将小图像合并为一个而不在内存中分配完整图像

问题描述 投票:2回答:1

我必须使用Java编写并行图像处理脚本,其目的是将图像划分为任意大小的图块,对其进行处理,然后重新组装最终图像。

现在我已经创建了一个函数:

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

将图像的区域作为BufferedImage返回,然后我将对其进行处理,并将该区域放置在最终图像的正确位置。

因此,我尝试制作一个函数replaceImg,该函数使用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异常。

java image-manipulation
1个回答
3
投票

只要您可以使用24位PNG文件作为输出,我就会为您提供可行的解决方案(根据GPL许可:

PngXxlWriter类允许“逐行”编写PNG文件。这意味着您可以在10,000行中写出10000x10000(宽*高)像素的图像。 256像素(10000 * 256)。

通常,这会将内存使用量降低到实际水平。

可以在这里找到所有必需的类:

PngXxlWriter是主要类。通过调用其方法writeTileLine,可以在输出图像中添加新行。

https://sourceforge.net/p/mobac/code/HEAD/tree/trunk/MOBAC/src/main/java/mobac/utilities/imageio/

© www.soinside.com 2019 - 2024. All rights reserved.