如何从大型图像中删除图像元数据而又不会用Java占用内存 [英] How to remove image metadata from large images without out of memory in Java

查看:48
本文介绍了如何从大型图像中删除图像元数据而又不会用Java占用内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从图像中删除元数据,但是当图像太大时,我得到了OOM.现在我正在使用ImageIO.

I need to remove metadata from images but when images are too large I get OOM. Right now I'm using ImageIO for that.

BufferedImage image = ImageIO.read(new File("image.jpg"));
ImageIO.write(image, "jpg", new File("image.jpg"));

问题是 ImageIO.read(...)会将整个文件读入内存,这在我处理太大的图像时会导致内存不足.

Problem is that ImageIO.read(...) will read the whole file into memory, which causes OutOfMemory when I'm processing images that are too big.

我可以尝试使用CommonsImaging( https://commons.apache.org/正确/commons-imaging/sampleusage.html ),但看起来它仅支持JPEG(ExifRewriter类).

I could try using CommonsImaging (https://commons.apache.org/proper/commons-imaging/sampleusage.html) but looks like it supports only JPEG (ExifRewriter class).

不能更改VM的内存配置,我需要支持的不仅仅是JPEG文件.

Changing the memory config for the VM is not an option and I need to support more than just JPEG files.

有什么想法可以做到这一点而又不会导致内存不足吗?

Any ideas how to do that without incurring into Out of Memory?

推荐答案

您可以尝试通过流式传输复制图像,并在流式传输期间应用过滤器以删除元数据来进行尝试.

You could try it by making a copy of the image via streaming and during the streaming apply a filter to remove the metadata.

可以按照以下步骤进行复制:

The copying could be done as follows:

    InputStream is = null;
    OutputStream os = null;
    try {
        // Source and Destination must be different 
        is = new FileInputStream(new File("path/to/img/src"));
        os = new FileOutputStream(new File("path/to/img/dest"));

        // Limit buffer size further is necessary!
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0) {
            // Apply removal of metadata here!!!
            os.write(buffer, 0, length);
        }
    } finally {
        is.close();
        os.close();
    }

请注意,原始文件和克隆文件不能相同,因此可能有必要删除原始文件,然后再重命名目标文件(如果您希望它们相同).

Note that the original and clone can't be the same so it might be necessary to delete the original and rename the destination file afterwards (if you want to the them the same).

代替普通的 outputstream ,您还可以创建自己的 FilteredOutputstream 并使用它.

Instead of a normal outputstream you could also create your own FilteredOutputstream and use that instead.

这篇关于如何从大型图像中删除图像元数据而又不会用Java占用内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆