%20%E3%81%A7%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%82%88%E3%81%84%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%81%8B%3F.png)
バージョン管理のために、多数のファイルを変換およびサイズ変更するスクリプトで 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,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 を正常に動作させることをあきらめ、タイムスタンプのバグを除けば 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 ではファイルが同一であると表示されます。