java - 如何在不使用 Java 将图像加载到内存的情况下裁剪图像

标签 java image image-processing crop

有没有办法在不将整个图像加载到内存中然后裁剪的情况下裁剪图像?

场景是我有一个非常非常大的图像文件,并且我有一个直角坐标列表,我需要从大图像中裁剪出这些直角坐标。图像太大了,我不能直接将它加载到内存中。有没有一种技术可以流式传输图像并找到要裁剪的起点和终点?如果我必须为每组坐标多次执行此步骤,请不要介意。哦,是的,假设图像是 JPG/PNG/TIFF 格式,哪种格式最容易处理。

如果对 native 库有任何依赖性,应该能够在 Windows 和 Linux 上运行。

谢谢。

最佳答案

您可以使用 libvips 来执行此操作 - 它适用于 Linux、OSX 和 Windows。

为了开始设置,让我们使用 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

缩小尺寸,仔细看是这样的,左上角是红色矩形,右下角是蓝色矩形:

enter image description here

重量为 800 MB:

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

现在让我们使用 libvips(仅在命令行中)提取左上角和右下角(很容易识别 - 你看到我在那里做了什么吗?):

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

enter image description here

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

enter image description here

这两个命令都使用了大约 120MB 的内存。我不相信 libvips 有 Java 绑定(bind),但我认为您可以使用 fork()exec() 东西或使用类似的东西C 的 system() 函数。

关于java - 如何在不使用 Java 将图像加载到内存的情况下裁剪图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33400335/

相关文章:

java - 3.0 中的 Spring SimpleFormController

java - 在 Android 应用程序中访问 C++ Web 服务

java - 具有多个关联的 Hibernate 提取

arrays - Firebase 存储异步图像下载顺序不正确

PHP 脚本加载大约需要 15 秒

c# - Windows 窗体 C# 中的图片框和面板

java - 对于图像模式识别,使用 OpenCV 还是 Java

android - xml图像占用了太多内存 - android

image-processing - 绘图数字化-从图形图像中抓取样本值

java - 如何使输出为 "Avocado Roll, Salmon Temaki, California Roll, Miso Soup"等。我不知道如何正确使用 substring 方法