Java 将小图像合并为一个图像,而无需在内存中分配完整图像

Java 将小图像合并为一个图像,而无需在内存中分配完整图像,java,image-manipulation,Java,Image Manipulation,我必须用java制作一个并行图像处理脚本,其思想是将图像分成任意大小的分块,处理它们,然后重新组装最终的图像 现在我已经创建了一个函数: public static BufferedImage readImg (String path, int startx, int starty, int w, int h) 它将图像的区域返回为BuffereImage,然后我将对其进行处理,并将该区域放置在最终图像的正确位置 因此,我尝试创建一个函数writeImg,它使用replacePixels方法只

我必须用java制作一个并行图像处理脚本,其思想是将图像分成任意大小的分块,处理它们,然后重新组装最终的图像

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

public static BufferedImage readImg (String path, int startx, int starty, int w, int h)
它将图像的区域返回为BuffereImage,然后我将对其进行处理,并将该区域放置在最终图像的正确位置

因此,我尝试创建一个函数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异常。

只要您可以使用24位PNG文件作为输出,我为您提供了一个可行的解决方案(在GPL许可下):

PngXxlWriter类允许“逐行”写入PNG文件。这意味着您可以在例如256像素(10000*256)的行中写入10000x1000(宽*高)像素的图像

通常,这会将内存使用率降低到实际可用的水平

可在此处找到所有必需的类:

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


哇,快速回答,好吧,那很好,还有一件事,你知道为什么替换像素不能与jpeg图像一起使用吗?用其他语言或其他方式做这件事还有其他方法吗?如果行仍然足够大,无法放入vjm的内存,那么问题仍然存在。此外,您需要按顺序为其提供行,并行线程不可能按顺序完成。我猜替换像素不起作用,因为JPEG是有损压缩。你试过用PNG做这个吗?或者任何其他的图像格式?@Alex88:如果可能的话,在JPEG图片上做这件事将是一个巨大的难题,因为JPEG是如何编码的。关于按顺序提供行,那么只需在最大n个线程上生成(无论如何,拥有n个比内核数量大得多的线程是没有意义的),这样就不会消耗太多内存,并且在处理一个“正方形”时,将其放入优先级队列中。只有当您有正确的元素可用时,才可以退出队列。冲洗并重复。@SyntaxT3rr0r不,我将在具有map reduce框架的计算机集群上执行此操作,而不是在单个pc上。