简体   繁体   English

如何使用 Java 裁剪图像而不将其加载到内存中

[英]How do I crop an image without loading it into memory using Java

Is there a way to crop an image without having the load the entire image into memory and cropping it then?有没有办法裁剪图像而不必将整个图像加载到内存中然后裁剪它?

The scenario is that I have a really really big image file and I have a list of rectangular coordinates that I need to crop out of the big image.场景是我有一个非常大的图像文件,我有一个直角坐标列表,我需要从大图像中裁剪出来。 The image is so huge I can't directly load it into memory.图像太大了,我无法将其直接加载到内存中。 Is there a technique I can stream the image and sort of find the start and end points to crop?有没有一种技术可以流式传输图像并找到要裁剪的起点和终点? Don't mind if I have to perform this step many times for each set of coordinates.不要介意我是否必须为每组坐标多次执行此步骤。 Oh yeah, assuming the images are of format JPG/PNG/TIFF which ever one is easiest to work with.哦,是的,假设图像是 JPG/PNG/TIFF 格式,这是最容易使用的格式。

Should be able to run on Windows and Linux should there be any dependencies on native libraries.如果对本机库有任何依赖性,应该能够在 Windows 和 Linux 上运行。

Thanks.谢谢。

You can use libvips to do this - it is available for Linux, OSX and Windows.您可以使用libvips来执行此操作 - 它适用于 Linux、OSX 和 Windows。

To get set up, let's use ImageMagick to create a big image (10,000x10,000) that is difficult to compress because it is full of random noise:为了进行设置,让我们使用 ImageMagick 创建一个难以压缩的大图像 (10,000x10,000),因为它充满了随机噪声:

convert -size 10000x10000 xc:gray +noise random  \
   -fill red  -draw "rectangle 0,0 100,100"      \
   -fill blue -draw "rectangle 9900,9900 10000,10000" BigBoy.tif

Reduced in size, it looks like this, with a red rectangle in the top-left and a blue rectangle in the bottom-right if you look closely:缩小后,它看起来像这样,如果仔细观察,左上角有一个红色矩形,右下角有一个蓝色矩形:

在此处输入图片说明

and weighs in at 800 MB:并重达 800 MB:

-rw-r--r--@  1 mark  staff  800080278  5 May 12:08 BigBoy.tif

Now let's use libvips (just at the command-line) to extract the top-left and bottom-right corners (which are readily identifiable - did you see what I did there?):现在让我们使用libvips (仅在命令行中)提取左上角和右下角(很容易识别 - 你看到我在那里做了什么吗?):

vips im_extract_area BigBoy.tif topleft.jpg 0 0 200 200 --vips-leak
memory: high-water mark 118.85 MB

在此处输入图片说明

vips im_extract_area BigBoy.tif bottomright.jpg 9800 9800 200 200 --vips-leak
memory: high-water mark 118.85 MB

在此处输入图片说明

Both commands used around 120MB of memory.这两个命令都使用了大约 120MB 的内存。 I don't believe there are Java bindings for libvips , but I presume you can fork() and exec() stuff or use something like C's system() function.我不相信libvips有 Java 绑定,但我认为你可以fork()exec()东西或使用类似 C 的system()函数的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM