我正在寻找一些关于如何构建一个非常低内存映像大小调整程序的建议,该程序将作为我在linux中的nodejs应用程序的子进程运行。
我正在寻找的解决方案是一个linux可执行文件,它将使用stdin获取base64字符串图像(从客户端上传),将照片大小调整为指定大小,然后通过stdout将生成的图像数据泵回。
我调查了image magick,这可能是我最终使用的内容,但我想我会问,看看是否有人有建议。
非常感谢C / C ++中的库或预编译可执行文件示例的建议。另外一个有用的答案将包括低内存图像大小调整的一般策略。
谢谢
答案 0 :(得分:9)
根据您要支持的图像格式,几乎可以通过一次仅解码几行并在写入输出后丢弃数据来执行增量解码和缩放。但是,它可能需要编写您自己的代码或调整现有的解码器库来支持这种操作。
值得注意的是,通过简单地跳过高频系数和使用较小的IDCT,可以有效地减小巨型jpegs的尺寸。例如,为了在半宽和半高处解码,丢弃除系数的左上象限之外的所有象限(水平和垂直频率<4)并且在它们上使用4×4IDCT而不是通常的8×8。 libjpeg
解码器和libavcodec
解码器都支持2次幂缩放(1/2,1 / 4或1/8)的此操作。这种方法可能不需要增量解码/扩展。
您可以使用djpeg -scale 1/4 < src.jpg | cjpeg > dest.jpg
进行试用。如果你想要一个固定的输出尺寸,你可能首先按1/2,1/4或1/8中的任何一个进行缩放,使你最接近所需的尺寸而不会变低,然后执行插值以进入最后一步,例如djpeg -scale 1/4 < src.jpg | convert pnm:- -scale 640x480 dest.jpg
。
答案 1 :(得分:3)
当处理非常大的图像(例如0.25 GPix及更大)时,ImageMagick使用~2 GB ram,即使使用djpeg首先解码JPEG图像也是如此。
此命令链将仅使用约3 MB RAM来调整任何大小的JPEG图像:
djpeg my-large.jpg | pnmscale -xysize 16000 16000 | cjpeg > scaled-large.jpg
答案 2 :(得分:1)
GraphicsMagick通常是ImageMagick的更好版本,我会看一下。如果你真的需要快速的东西,你可能想要像libjpeg这样的东西 - 当你说你想要的东西是非阻塞的IO时,你想要做的操作是相对CPU限制的(即解码图像,然后尝试调整大小)它)。
答案 3 :(得分:1)
如果有什么,这只是他所描述的样本之后的样本:
import sys
from PIL import Image
import binascii
import cStringIO
x,y = sys.stdin.readline().strip().split(' ')
x,y = int(x), int(y)
img = Image.open(cStringIO.StringIO(binascii.b2a_base64(sys.stdin.read())).resize(x,y)
img.save(sys.stdout, format="png")
因为必须读取输入,解码,调整大小和编码,并将其写出来无法将所用内存的大小减小到小于输入图像的大小
答案 4 :(得分:1)
在性能方面,没有什么能超越英特尔集成性能基元。如果你负担得起,我强烈建议你使用它。
否则只需实现自己的调整大小例程。 Lanczos给出了相当不错的结果,尽管它不会非常快。
编辑:我强烈建议你不要使用Image Magick或Graphics Magick。它们都是很棒的库,但是设计用于完全不同的目的 - 处理许多文件格式,深度,像素格式等。它们牺牲了我提到的东西的性能和内存效率。
答案 5 :(得分:0)
您可能需要:https://github.com/zhangyuanwei/node-images
Nodejs的跨平台图像解码器(png / jpeg / gif)和编码器(png / jpeg)