如何使用 ImageMagick 以可重现的方式进行转换(无时间戳)?

如何使用 ImageMagick 以可重现的方式进行转换(无时间戳)?

我正在尝试在脚本中使用 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 显示文件是相同的。

相关内容