ImageMagick で JPEG や PNG を処理していると、次のような警告に出会うことがあります。
identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.
これは画像に埋め込まれた XMP メタデータを ImageMagick が XML として読もうとして、壊れていると判断したときの警告です。画像のピクセル変換そのものが失敗しているとは限りません。
この記事では、壊れた XMP 入りの JPEG を手元で作って、xmp:validate を付けたときに何が起きるかを確認します。
xmp:validate は何をしているのか
xmp:validate は ImageMagick の -define で指定する設定です。
公式の defines ページでは、xmp:validate={true,false} は「画像に埋め込まれた XMP プロファイルを検証する」と説明されています。
XMP は、ざっくり言うと画像に入る XML 形式のメタデータです。撮影・編集ソフト・権利情報・説明文などが入ることがあります。ImageMagick 側では、XML delegate が有効なビルドだと、この XMP を XML として読めるか確認できます。
手元の ImageMagick 7.1.2-27 では、xmp:validate=true を明示したときに CorruptImageProfile ... (XMP) の警告を確認しました。公式説明には「デフォルトで検証」とありますが、少なくともこの環境では、素の identify や変換では警告が出ませんでした。バージョンやビルド設定で挙動が違う可能性があるので、まず自分の環境で確認するのがよいです。
確認環境は以下です。
Version: ImageMagick 7.1.2-27 Q16-HDRI aarch64 e4c2b403b:20260705 https://imagemagick.org
Features: Cipher DPC HDRI Modules
Delegates (built-in): bzlib freetype heic jng jpeg lcms ltdl lzma png tiff webp xml zlib zstd
壊れた XMP 入り JPEG を作る
まず、わざと XML として壊れた XMP ファイルを作ります。
printf '\xff\xfe\x00\x00not xml\n' > bad.xmp
magick -size 32x32 xc:white base.jpg
普通に -profile bad.xmp すると環境によっては追加時点で警告されるので、ここでは xmp:validate=false を付けて、壊れた XMP を持つ JPEG を作ります。
magick base.jpg -define xmp:validate=false -profile bad.xmp bad.jpg
XMP プロファイルが入っていることは identify -verbose で確認できます。
magick identify -verbose bad.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'
出力:
Profiles:
Profile-xmp: 12 bytes
xmp:validate=true で警告を再現する
xmp:validate=true を付けて identify します。
magick identify -define xmp:validate=true bad.jpg
echo $?
手元ではこうなりました。
bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
identify: CorruptImageProfile `bad.jpg' (XMP) @ warning/profile.c/ValidateXMPProfile/2011.
0
ここで大事なのは、終了コードが 0 のままだったことです。つまり、少なくともこのケースでは「警告は出るが、コマンドとしては成功」です。スクリプトが stderr の文字列を見て失敗扱いしている場合は別ですが、終了コードだけを見る処理なら失敗にはなりません。
警告だけ消すなら -quiet
ログに警告を出したくないだけなら、-quiet で警告は消えました。
magick identify -quiet -define xmp:validate=true bad.jpg
echo $?
出力:
bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.001
0
ただし、これは警告を黙らせるだけです。壊れた XMP は画像内に残ります。
検証を止めるなら xmp:validate=false
XMP の検証自体を止めるなら、入力ファイルより前に -define xmp:validate=false を置きます。
magick identify -define xmp:validate=false bad.jpg
echo $?
出力:
bad.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 210B 0.000u 0:00.000
0
変換でも同じ考え方です。
magick -define xmp:validate=false bad.jpg out.png
-define は入力を読む前に効かせたいので、迷ったら入力ファイル名より前に置くのが安全です。
XMP を消すなら +profile xmp
壊れた XMP が不要なら、検証を止めて読み込み、そのあとで XMP プロファイルだけ削除します。
magick -define xmp:validate=false bad.jpg +profile xmp clean-no-xmp.jpg
echo $?
出力:
0
削除後のファイルを確認します。
magick identify -verbose clean-no-xmp.jpg 2>/dev/null | grep -Ei 'profiles|profile-xmp'
出力は空でした。さらに、削除後のファイルは xmp:validate=true で読んでも警告が出ません。
magick identify -define xmp:validate=true clean-no-xmp.jpg
echo $?
出力:
clean-no-xmp.jpg JPEG 32x32 32x32+0+0 8-bit Grayscale Gray 256c 165B 0.000u 0:00.000
0
すべてのメタデータを消してよいなら -strip
XMP だけでなく、EXIF や ICC などのプロファイル、コメント類も落としてよいなら -strip が使えます。
magick -define xmp:validate=false bad.jpg -strip clean-strip.jpg
echo $?
出力:
0
-strip は画像を軽くしたいときには便利ですが、色管理の ICC プロファイルや撮影情報も落ちます。Web用サムネイルなら問題ないことが多い一方、印刷・写真管理・権利情報を残したい用途では雑に使わない方がよいです。
どれを使うべきか
目的別に分けると、こうです。
目的 コマンド例 注意 警告をログに出したくないだけ magick identify -quiet -define xmp:validate=true bad.jpgXMP は残る XMP 検証をスキップしたい magick -define xmp:validate=false input.jpg output.png壊れた XMP を温存する場合がある XMP だけ消したい magick -define xmp:validate=false input.jpg +profile xmp output.jpgXMP 内の説明・権利情報も消える 全メタデータを消してよい magick -define xmp:validate=false input.jpg -strip output.jpgEXIF/ICC/コメントも消える
Webアプリの画像変換で「ユーザー投稿画像を縮小して表示するだけ」なら、-define xmp:validate=false と -strip の組み合わせで済むことが多いです。逆に、写真のメタデータや色プロファイルを大事にする処理では、-strip ではなく +profile xmp のように削除対象を絞った方が安全です。
さいごに
xmp:validate は、画像のピクセルではなく XMP メタデータの検証に関わる設定です。CorruptImageProfile ... (XMP) が出ても、まずは終了コード、出力ファイル、XMP が必要かどうかを分けて見た方がよいです。
今回の手元検証では、警告が出ても終了コードは 0、-quiet は警告を隠すだけ、xmp:validate=false は検証を止める、+profile xmp と -strip はメタデータを実際に削除する、という違いが確認できました。
関連: