我正在尝试在脚本中使用 ImageMagick 来转换和调整大量文件的大小以进行版本控制。我需要每次转换文件的时间都相同,这样 git 就不会提交刚刚更新了时间戳的文件。不幸的是,ImageMagick 坚持要为每个图像添加创建和修改时间戳,这会让 git 重新提交每个文件。
我已经搜索了很多有关此问题的信息,并尝试了以下标志:
-define png:exclude-chunks=date
+set date:create +set date:modify
-strip
这些均未导致可重复的过程:
-define png:排除块=日期
stephen@Saturn ~/test (git)-[master] % convert input.png -define png:exclude-chunks=date -resize 100x100 1.png
stephen@Saturn ~/test (git)-[master] % convert input.png -define png:exclude-chunks=date -resize 100x100 2.png
stephen@Saturn ~/test (git)-[master] % diff 1.png 2.png
Binary files 1.png and 2.png differ
stephen@Saturn ~/test (git)-[master] % cmp -l 1.png 2.png
125 41 42
126 67 0
127 322 101
128 321 101
129 35 353
130 64 370
+设置日期:创建 +设置日期:修改
stephen@Saturn ~/test (git)-[master] % convert input.png +set date:create +set date:modify -resize 100x100 1.png
stephen@Saturn ~/test (git)-[master] % convert input.png +set date:create +set date:modify -resize 100x100 2.png
stephen@Saturn ~/test (git)-[master] % diff 1.png 2.png
Binary files 1.png and 2.png differ
stephen@Saturn ~/test (git)-[master] % cmp -l 1.png 2.png
125 51 52
126 71 0
127 375 211
128 260 230
129 272 141
130 73 360
-条
stephen@Saturn ~/test (git)-[master] % convert input.png -strip -resize 100x100 1.png
stephen@Saturn ~/test (git)-[master] % convert input.png -strip -resize 100x100 2.png
stephen@Saturn ~/test (git)-[master] % diff 1.png 2.png
Binary files 1.png and 2.png differ
stephen@Saturn ~/test (git)-[master] % cmp -l 1.png 2.png
110 41 45
111 241 246
112 235 360
113 264 160
114 252 263
如何使用 ImageMagick 完成可重复的转换?
答案1
您需要将 ImageMagick 更新至 6.9.1-3 或更高版本,然后问题中的所有命令都会创建可重现的图像。
我发现以下内容变更日志:
2015-04-20 6.9.1-3 Cristy <quetzlzacatenango@image...> * 支持 -define compose:clamp=false 选项(参考 https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=26946)。 * 不要在 SeekBlob() 中扩展任何用户提供的图像缓冲区(错误报告 来自 a.chernij@corp...)。 * 改进了可重复的构建(参考 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=783933)。 * 绘制一个宽度和高度为 1 的矩形(参考 https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=24874)。
在发现 ArchLinux 上的 ImageMagick 运行良好,与 Ubuntu 16.04 上的 ImageMagick 相反后,我发现了变更日志条目。
ArchLinux(良好、可重现的图像):
$ convert --version
Version: ImageMagick 6.9.8-8 Q16 x86_64 2017-05-30 http://www.imagemagick.org
Ubuntu 16.04(糟糕,每次都是不同的图像):
$ convert --version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2017-05-26 http://www.imagemagick.org
答案2
我发现-define png:exclude-chunks=date,time
这是必要的。仅仅排除date
块是不够的。
单一选项就足够了;我不需要-strip
或导出特定的时间戳SOURCE_DATE_EPOCH
(这在其他地方已有建议)。
最后,查看差异diff <(xxd 1.png) <(xxd 2.png)
是我喜欢的方式,查看二进制和 ascii(有助于查看块 ID 和时间戳出现的位置)。
仅供参考,仅排除date
:
8,9c8,9
< 00000070: 0000 0774 494d 4507 e503 030a 1d0f bd0c ...tIME.........
< 00000080: 01f4 0000 8000 4944 4154 78da ecdd 7578 ......IDATx...ux
---
> 00000070: 0000 0774 494d 4507 e503 030a 1c19 50c3 ...tIME.......P.
> 00000080: 85e4 0000 8000 4944 4154 78da ecdd 7578 ......IDATx...ux
答案3
我已经放弃让 ImageMagick 正常运行,而是转而使用 GraphicsMagick,它似乎具有 ImageMagick 的所有功能,除了这个时间戳错误:
stephen@Saturn ~/test (git)-[master] % gm convert -resize 100x100 input.png 1.png
stephen@Saturn ~/test (git)-[master] % gm convert -resize 100x100 input.png 2.png
stephen@Saturn ~/test (git)-[master] % diff 1.png 2.png
stephen@Saturn ~/test (git)-[master] % cmp -l 1.png 2.png
识别显示 2 个不同的时间戳,但它是从文件属性而不是嵌入的元数据中获取的,并且 diff / cmp 显示文件是相同的。