ImageMagick convert を再現可能な方法 (タイムスタンプなし) で使用するにはどうすればよいでしょうか?

ImageMagick convert を再現可能な方法 (タイムスタンプなし) で使用するにはどうすればよいでしょうか?

バージョン管理のために、多数のファイルを変換およびサイズ変更するスクリプトで ImageMagick を使用しようとしています。git がタイムスタンプを更新したばかりのファイルをコミットしないように、ファイルを毎回同じ時間に変換する必要があります。残念ながら、ImageMagick は各イメージに作成および変更のタイムスタンプを追加する必要があるため、git はすべてのファイルを再度コミットすることになります。

私はこの問題についていろいろ調べて、以下のフラグを試しました。

-define png:exclude-chunks=date
+set date:create +set date:modify
-strip

いずれも再現可能なプロセスには至っていません。

-define png:exclude-chunks=日付

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)。

Ubuntu 16.04 上の ImageMagick とは異なり、ArchLinux 上の 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,timedateチャンクだけを除外するだけでは不十分でした。

-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 を正常に動作させることをあきらめ、タイムスタンプのバグを除けば ImageMagick のすべての機能を備えていると思われる GraphicsMagick を使用することにしました。

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

Identify では 2 つの異なるタイムスタンプが表示されますが、これは埋め込まれたメタデータではなくファイル プロパティから取得されており、diff / cmp ではファイルが同一であると表示されます。

関連情報