インスタグラムが保存する画像のフォーマットに翻弄される

はじめに

最近私の環境で、インスタグラムのアプリが保存した写真がブログにアップできない、という不可解な現象が発生しました。以下はその謎の解明にあたった記録です。

使用した環境は以下の通りです。

  • スマートフォン:Xperia 10Ⅳ (Docomo SO-52C)
  • OS:Android 13
  • インスタグラムアプリのバージョン:2023年4月1日〜25日に随時更新された最新バージョン
    • 2023/04/24更新 280.0.0.18.114
    • それ以前の更新履歴は不明
  • ブログの CMS:WordPress 6.2

インスタの「元の投稿を保存」機能

インスタグラムをお使いの皆さん、元の投稿を保存 (投稿した写真をスマホに保存する機能) ってどうしてますか?

元の写真があるんだからそんなのストレージの無駄遣い!オフにするに決まってる!という方も多いと思いますが、私はインスタ投稿時のクロップ (画角切り取り) や解像度の調整がそれなりに便利なのでオンにしています。例えばインスタの投稿を貼り付けて作っているテレワークランチのまとめのようなブログ記事で、アイキャッチ画像に使ったりしています。

突然のアップロード不能

そんなわけで先日もこちらの記事を執筆し…

いつものように WordPress にアイキャッチ画像をアップロードしようとしたのですが、何度やってもメディアライブラリに画像が登録されない、というトラブルが発生。試しにオリジナル画像をアップしたら登録できたので、この日はそれで何とか公開しました。

でもなぜなんでしょう。ブログ記事の設定画面の「アイキャッチ画像」のインターフェースではエラーも何も表示されないので原因の探りようがありません。そこで管理画面からメディア→新規追加で写真をアップしてみました。

すると、こんなことに。

権限って、オレここの管理者だし。試しに別の画像では…

あ、これは通るのか。

いろいろ調べると、画像フォーマットが WordPress の対応外だったりする場合にも「このファイルタイプをアップロードする権限がありません」というメッセージが出るようです。権限という言葉に惑わされましたが、今回はファイルタイプの方が問題のようです。

でも両方とも拡張子は .jpg で、JPEG 画像のはずです。JPEG でもファイルによって何か違いがあるのかな?それともメタデータに WordPress が拒否するような要素があるとか?

甘い!.jpg なら何でも JPEG だと思うなよ!

いや、この時点ではまだ、インスタが .jpg として保存したファイルなら JPEG だろうと信じていたのです。

しかし、画像ファイルを PC にコピーし、何の気なしにダブルクリックしたら…表示できない!

そんなバカな。さらに Linux (WSL2) に持って行って ImageMagick の identify コマンドで確認したら…

$ identify IMG_20230417_131235_592.jpg
identify-im6.q16: Not a JPEG file: starts with 0x00 0x00 `IMG_20230417_131235_592.jpg' @ error/jpeg.c/JPEGErrorHandler/322.

Not a JPEG file ですと!?

じゃあ何なのよ、ということでバイナリデータを確認してみました。イマドキの人なら何使うんだろ。私は od コマンドです。Octal dump ですね。

$ od -t x1a IMG_20230417_131235_592.jpg | head
0000000  00  00  00  18  66  74  79  70  68  65  69  63  00  00  00  00
        nul nul nul can   f   t   y   p   h   e   i   c nul nul nul nul
...

何やら heic とか書いてあります。調べてみると HEIF (High Efficiency Image File Format) というフォーマットでした。実はこれ、私は存在自体を知らなかったのですが、高画質高効率が特徴で iPhone 等では標準で使われているものなのですね。拡張子は通常 .heic です。だからファイルの中には heic と書いてあるのか。詳しくは Wikipedia の説明 等をご参照ください。

それにしても、ファイルの拡張子が .jpg だからといって JPEG である保証がないのは確かにその通りなんだけど、慣行というものがあるではないですか。実際 .heic が普通は使われる訳ですし。超メジャーアプリである Instagram が画像を HEIF に変換しておきながら拡張子は .jpg のままというのは、どーなのよ?

ちなみに元の写真についても念のため確認したところ、ちゃんと JPEG でした。

一方、過去のインスタが保存した写真はというと、

$ od -t x1a IMG_20230414_130016_061.jpg | head
0000000  ff  d8  ff  e1  00  ca  45  78  69  66  00  00  4d  4d  00  2a
        del   X del   a nul   J   E   x   i   f nul nul   M   M nul   *
...
$ od -t x1a IMG_20230401_162358_664.jpg | head
0000000  52  49  46  46  a6  38  03  00  57  45  42  50  56  50  38  58
          R   I   F   F   &   8 etx nul   W   E   B   P   V   P   8   X
...

4/14の写真は普通の JPEG、そしてなんと、4/1の写真は WebP です。WebP も高効率な画像フォーマット。詳しくは Wikipedia 参照

WebP は WordPress でも対応しているのでこれまで問題なかったわけですが、私は知らないうちに JPEG じゃない画像をアップしていたということです。一方 HEIF は今のところ WordPress で未対応なのでアップロードに失敗した、というのが真相でした。

Instagram フォルダの中身はカオス

こうなると、他のファイルがどうなっているのかも気になります。試しに2023年4月1日〜25日のファイルをまとめて確認してみました。該当ファイルを入れたディレクトリで実行したコマンドは下記の通り。本当なら判定プログラムを書くところですが、面倒なのでバイナリダンプを取るところまでをワンライナーで書いて、出力は目視確認しました。

$ for img in *.jpg; do echo $img; od -t x1a $img | head -n 2; done

結果は以下の通り。ちなみに画像ファイル名は IMG_yyyymmdd_hhmmss_nnn.jpg (yyyymmdd は年月日、hhmmss は時分秒、nnn は何等かの数字) となっているようです。

ファイル名フォーマット
IMG_20230401_162358_573.jpgWEBP
IMG_20230401_162358_664.jpgWEBP
IMG_20230401_162358_697.jpgWEBP
IMG_20230403_123304_591.jpgJPEG
IMG_20230404_131002_210.jpgJPEG
IMG_20230405_130356_135.jpgJPEG
IMG_20230406_131145_598.jpgWEBP
IMG_20230406_131145_687.jpgWEBP
IMG_20230407_132732_380.jpgWEBP
IMG_20230407_132732_524.jpgWEBP
IMG_20230408_142602_893.jpgJPEG
IMG_20230409_081510_850.jpgJPEG
IMG_20230409_211643_689.jpgWEBP
IMG_20230409_211643_836.jpgWEBP
IMG_20230410_124051_536.jpgJPEG
IMG_20230411_130819_880.jpgJPEG
IMG_20230411_131505_989.jpgWEBP
IMG_20230411_131506_094.jpgWEBP
IMG_20230411_131506_188.jpgWEBP
IMG_20230411_131506_246.jpgWEBP
IMG_20230411_131506_319.jpgWEBP
IMG_20230411_131506_347.jpgWEBP
IMG_20230411_131506_394.jpgWEBP
IMG_20230411_131506_426.jpgWEBP
IMG_20230411_131506_448.jpgWEBP
IMG_20230411_132606_182.jpgJPEG
IMG_20230412_131536_907.jpgWEBP
IMG_20230412_131537_151.jpgWEBP
IMG_20230412_132051_630.jpgJPEG
IMG_20230413_130833_449.jpgJPEG
IMG_20230414_130016_061.jpgJPEG
IMG_20230416_191009_649.jpgJPEG
IMG_20230417_131235_472.jpgHEIF
IMG_20230417_131235_592.jpgHEIF
IMG_20230417_131235_629.jpgHEIF
IMG_20230418_135035_526.jpgJPEG
IMG_20230419_002626_585.jpgJPEG
IMG_20230419_122204_197.jpgJPEG
IMG_20230420_124352_493.jpgHEIF
IMG_20230420_124352_656.jpgHEIF
IMG_20230420_124352_719.jpgHEIF
IMG_20230421_123947_678.jpgHEIF
IMG_20230421_123947_840.jpgHEIF
IMG_20230421_174958_103.jpgHEIF
IMG_20230421_174958_312.jpgHEIF
IMG_20230421_174958_346.jpgHEIF
IMG_20230421_184123_275.jpgHEIF
IMG_20230421_184123_548.jpgHEIF
IMG_20230424_125055_681.jpgHEIF
IMG_20230424_125055_858.jpgHEIF
IMG_20230425_131454_342.jpgHEIF
IMG_20230425_131454_476.jpgHEIF

うわ、どゆこと?途中までは WebP とJPEG が混在し、4月17日を境に WebP は姿を消して HEIF が登場、でも相変わらず JPEG も混在してます。カオスです。

謎の解明

おそらく画像の再エンコードはスマホアプリが行っているのだと思いますので、最後に WebP で保存された4月12日以降かつ4月17日以前にアプリのバージョンアップがあったのでしょう。これについてはアプリの更新履歴を探したのですが見つけられませんでした。どこを見ればわかるかご存知の方がいらっしゃいましたら教えていただけると助かります。

でも、なぜ JPEG が混在しているのでしょう。改めてファイル名をよーく見ると、WebP や HEIF に変換されたものはファイル名の yyyymmdd_hhmmss の部分が同じものが必ず複数あるのに対し、JPEG は同じものがありません。お、解決の糸口?

自分の投稿内容とも照らし合わせると、日付と時刻はアップロードのタイミングを指すようです。同じ日付と時刻の複数の写真は複数枚まとめてアップしたものを意味します。つまり、単独の写真でアップしたものは JPEG のまま、複数枚まとめてアップしたものは WebP もしくは HEIF に変換されている、ということになります。なるほどそういうことだったのか!

複数の写真を一度にアップする際の通信量を削減したい、という意図でしょうか。単一の写真については通信時間と再エンコード処理時間のトレードオフで再エンコードしないことにしたのかな?その辺は推測の域を出ませんが、実際行われていること自体は間違いないと思います。一部の画像の画像サイズも確認してみたところ、JPEG の画像はオリジナルの (クロップした) サイズのままであるのに対し、WebP や HEIF ではピクセル数も少なくなっていました。例えば元が 4000×3000 だったものを 3000×3000 にクロップしてアップした場合、1枚単独では 3000×3000 のままですが、WebP や HEIC では 1440×1440 になっていたという例がありました (異なるサイズだった例もあり、縮小の比率の規則性等は未確認)。つまり、インスタに複数枚の画像をまとめてアップすると解像度が落ちる、ということになります。知らなかったぞ!

まとめ

今回分かったことをまとめると以下の通りです。

  • インスタグラムの「元の投稿を保存」では、写真を1枚だけ単独で上げる時と複数枚まとめて上げる時で異なる画像フォーマット、異なるピクセル数が用いられる
    • 単独の時は JPEG でオリジナルのピクセル数のまま
    • 複数枚まとめて上げる時は、以前は WebP、現在は HEIF に再エンコードされ、ピクセル数も小さくなる
    • 上記の再エンコードに際してファイルの拡張子は変更されず、元の拡張子のまま保存される
  • WordPress は現時点 (バージョン 6.2) では HEIF に対応しておらず、メディアに同フォーマットの画像をアップロードしようとすると「このファイルタイプをアップロードする権限がありません」というメッセージが表示される

というわけで、個人的にはインスタのアプリが画像を再エンコードしても拡張子を変えない、ということにかなり衝撃を受けました。ニッチな話ですがどなたかの参考になるようなことがあれば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です