如何使用 ImageMagick 的转换命令链接图像转换?
我有一个原始图像(例如,1600x1200),我想为其创建一系列具有各种分辨率的缩略图:
- 900x0(即意味着图像按比例缩放到900像素宽)
- 700x0
- 0x550(即意味着图像按比例缩放至 550 像素高)
- 0x400
- 0x150
- 200x200(即裁剪并居中)
我可以使用 convert
命令单独处理每个转换。问题是不断地重新初始化convert
会造成巨大的资源浪费;最好将事物链接起来,以便 convert
可以重用其工作。
使用 ImageMagick 6.7.0-10 我尝试了以下操作(使用 +write
选项,请参阅 http://www.imagemagick.org/script/command-line-options.php#write),但它不起作用+write
命令似乎无法将图像恢复到原始状态:
convert '/tmp/original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*'\
-resize '900>' +write '/tmp/900.jpg'\
-resize '700>' +write '/tmp/700.jpg'\
-resize '200x' -crop '200x200+0+35' +repage +write '/tmp/200.jpg' \
-resize 'x550>' +write '/tmp/550.jpg'\
-resize 'x400>' +write '/tmp/400.jpg'\
-resize 'x150>' '/tmp/150.jpg'\
* 可读性目的
另外,我尝试了以下操作(使用 +clone
和 -delete
)。它似乎有效,但可能会变得更高效(也许使用 mpr:
, http://www.imagemagick.org/Usage/files/#mpr):
convert 'original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*' \
\(+clone -resize 'x150>' -write '150.jpg' \) \
-delete 1 \(+clone -resize 'x400>' -write '400.jpg' \) \
-delete 1 \(+clone -resize 'x550>' -write '550.jpg' \) \
-delete 1 \(+clone -resize '200x' -crop '200x200+0+35' +repage -write '200.jpg' \) \
-delete 1 \(+clone -resize '700>' -write '700.jpg' \) -delete 1 -resize '900>' '900.jpg' \
任何人都可以解释我在第一个示例中做错了什么(使用 +write
命令)?另外,谁能建议任何改进,以提高 CPU/内存效率?
回答后
我仍然很好奇为什么 +write
不起作用。
I've got an original image (say, 1600x1200) for which I want to create a series of thumbnails with a variety of resolutions:
- 900x0 (i.e. means that the image is scaled proportionally to 900 px wide)
- 700x0
- 0x550 (i.e. means that the image is scaled proportionally to 550 px tall)
- 0x400
- 0x150
- 200x200 (i.e. cropped and centred)
Individually, I can process each of these conversions with a convert
command. The problem is that it's a huge waste of resources to continually reinitialize convert
; it would be better to chain things so that convert
could reuse its work.
Using ImageMagick 6.7.0-10 I've tried the following (using the +write
option, see http://www.imagemagick.org/script/command-line-options.php#write), but it doesn't work as the +write
command appears to be ineffective in restoring the image to its original state:
convert '/tmp/original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*'\
-resize '900>' +write '/tmp/900.jpg'\
-resize '700>' +write '/tmp/700.jpg'\
-resize '200x' -crop '200x200+0+35' +repage +write '/tmp/200.jpg' \
-resize 'x550>' +write '/tmp/550.jpg'\
-resize 'x400>' +write '/tmp/400.jpg'\
-resize 'x150>' '/tmp/150.jpg'\
* end-of-line backslashes for readability purposes
Alternatively, I tried the following (using +clone
and -delete
). It seems to work, but could probably be made more efficient (perhaps with mpr:
, http://www.imagemagick.org/Usage/files/#mpr):
convert 'original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*' \
\(+clone -resize 'x150>' -write '150.jpg' \) \
-delete 1 \(+clone -resize 'x400>' -write '400.jpg' \) \
-delete 1 \(+clone -resize 'x550>' -write '550.jpg' \) \
-delete 1 \(+clone -resize '200x' -crop '200x200+0+35' +repage -write '200.jpg' \) \
-delete 1 \(+clone -resize '700>' -write '700.jpg' \) -delete 1 -resize '900>' '900.jpg' \
Can anyone explain what I'm doing wrong in the first example (with the +write
command)? Also, can anyone suggest any improvements to make things more CPU/memory efficient?
POST-ANSWER
I'm still curious why +write
doesn't work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
事实证明,使用
mpr:
是可行的方法(根据我在论坛等上看到的内容):注意:以防万一您错过了它,您不需要
- write
命令用于链中的最后一个图像。另请注意:在输出的文件上使用扩展名非常重要。如果省略它,
convert
不知道在写入它们时应该使用哪种格式(可能是因为将图像存储在mpr:
中会破坏该信息)。Turns out that using
mpr:
is the way to go (from what I've seen on forums and whatnot):NOTE: just in case you missed it, you don't need a
-write
command for the last image in the chain.ALSO NOTE: it's important that you use an extension on the files being output. If you omit it,
convert
doesn't know which format it should use when writing them (presumably because storing the image inmpr:
destroys that information).您误解了
+write
参数的含义。它不会撤消在写入操作之前执行的任何图像处理,它只会撤消由写入操作本身引起的任何处理。例如,假设您有一个 JPG 图像,并且执行以下操作:
< code>convertoriginal.jpg -scale 50% -writeoutput1.gifoutput2.jpg
会发生什么?
convert
将original.jpg
读取到内存并将其缩小到分辨率的一半。现在它应该将其写入output1.gif
,但由于 GIF 格式仅支持基于调色板的图像,因此它将图像转换为 256 色并写入 GIF 文件。现在它会将当前图像(已减少为 256 色)转换回真彩色(24 位 RGB)并将其写入output2.jpg
,因为 JPG 文件不支持基于调色板图像。尽管如此,JPG 看起来仍然非常像将 GIF 文件转换为 JPG(它将限制为大约 256 种不同的颜色)。现在让我们再次尝试同样的操作,但这次我们执行以下操作:
convertoriginal.jpg -scale 50% +write output1.gifoutput2.jpg
会发生什么?
convert
将original.jpg
读取到内存并将其缩小到分辨率的一半。现在它应该将其写入output1.gif
,但是,不修改它,这就是+write
说,所以它首先将图像克隆到内存中。它将克隆转换为 256 色并将结果写入output1.gif
。然后,它再次丢弃克隆,并继续处理克隆之前的图像。该图像现已写入output2.jpg
,这意味着这次output2.jpg
将是original.jpg
的缩小版本,而不是看起来像基于 256 调色板的图像。在任何情况下,缩放操作都不会被撤消,因为它与写入操作完全无关。如果要撤消缩放操作,则需要保存图像、缩放它、写入它,然后恢复它,或者克隆它、缩放它、写入它,然后丢弃克隆。无论哪种方式都应该同样快,因为在两种情况下在内存中执行的副本数量是相同的,只是命令行语法不同。
You misunderstood the meaning of the
+write
argument. It will not undo any of your image processing performed previous to the write operation, it will only undo any processing caused by the write operation itself.E.g. assume you have a JPG image and you do the following:
convert original.jpg -scale 50% -write output1.gif output2.jpg
What is going to happen?
convert
readsoriginal.jpg
to memory and shrinks it to half the resolution. Now it should write it tooutput1.gif
, but as the GIF format only supports images that are palette based, it will convert the image to 256 colors and write the GIF file. Now it will take the current image, which was reduced to 256 colors, convert it back to true color (24 Bit RGB) and write it tooutput2.jpg
, because JPG files don't support palette based images. Still, the JPG will look pretty much like if you had convert the GIF file to JPG (it will be limited to about 256 distinct colors).Now let's try the same thing again, but this time we do the following:
convert original.jpg -scale 50% +write output1.gif output2.jpg
What is going to happen?
convert
readsoriginal.jpg
to memory and shrinks it to half the resolution. Now it should write it tooutput1.gif
, however, without modifying it, that's what the+write
is saying, so it first clones the image in memory. It converts the clone to 256 colors and writes the result tooutput1.gif
. Then it discards the clone again and continues processing with the image it had prior to cloning. This image is now written tooutput2.jpg
, which means this time,output2.jpg
will be a downscaled version oforiginal.jpg
and not looking like a 256 color palette based image.Under no circumstances the scale operation is undone, because it is completely unrelated to the write operation. If you want to undo the scale operation, you need to either save the image, scale it, write it and then restore it, or clone it, scale it, write it and then discard the clone. Either way should be equally fast because the number of copies performed in memory is identical in both cases, it's just the command line syntax that is different.