iPhoneの写真を、公開できる形に変換する
定番のライブラリが1枚も開けませんでした。差し替えたうえで、EXIFを捨て、写り込みをぼかすところまでを一本の処理にした話です。
現地で撮った写真をサイトに載せるには、変換が要ります。iPhone の既定の保存形式は HEIC で、そのままではブラウザで表示できない環境が残るためです。長辺を縮め、JPEG にして、公開用のフォルダに置く。よくある前処理です。
定番のライブラリが全滅した
画像処理では定番のライブラリを使いました。内部の画像エンジンに HEIC 対応が同梱されているので、そのまま読めるはずでした。1枚も開けませんでした。
エラーは2種類で、シーク位置が不正だという内容と、その圧縮形式は組み込まれていないという内容です。原因は、素材が深度データを含む HEIC だったことでした。人物撮影などで生成される、奥行き情報が入った形式です。同梱のデコーダはこれを扱えませんでした。
ここで粘らず、デコードだけ別の言語のライブラリに任せることにしました。変換処理を1つのスクリプトに統一するより、開けることを優先した形です。結果として、画像処理は Python 側で完結する構成になりました。
「定番だから読めるはず」で時間を溶かしかけました。手元の素材で1枚試すのが、調べるより早い場面があります。
EXIF は引き継がない
変換で最も気をつけたのは、写真に埋まっている撮影情報です。EXIF には撮影地の緯度経度、端末の機種、撮影時刻が入りえます。観光サイトに載せる写真としては、どれも公開する必要がありません。
そこで、出力に EXIF を一切引き継がない方針にしました。ただし1つだけ例外があります。画像の向き(Orientation)です。これを捨てるだけだと、縦向きに撮った写真が横倒しで表示されます。向きの情報を実際のピクセルに焼き込んでから、EXIF ごと捨てるという順序にしました。
重要なのは、今回の素材に位置情報が入っていなかったことです。それでもこの処理を入れました。次のバッチで位置情報をオンにした写真が来たときに、素通りしてしまうからです。問題が起きてから対策を入れると、起きた1回ぶんは公開されてしまいます。
写り込みは、塗り潰さずにぼかす
屋外の写真には、車のナンバープレートや通行人が写ります。これらを隠す指定を、写真ごとにデータで持てるようにしました。指定は元画像に対する相対的な位置(0〜1の比率)で書きます。絶対座標にすると、出力サイズを変えたときに全部ずれるためです。
処理の順序も決めました。リサイズより前に隠すことで、あとから長辺の指定を変えても指定が効き続けます。
隠し方は塗り潰しではなく、強いぼかしにしました。理由は写真としての自然さです。そこに車や人が居たことは分かったほうがよい。真っ黒な四角が浮いていると、写真そのものが不自然になり、かえって視線を集めます。
この処理を一本にまとめた理由
- 手作業を残すと、忘れる。 EXIF を消し忘れた1枚は、消し忘れたことに誰も気づけない
- 設定をデータに持たせる。 どこをぼかすかは写真ごとに違うので、コードではなくデータ側に置く
- 変換をやり直せる状態を保つ。 元の HEIC は残し、公開用の JPEG は生成物として扱う
写真は今後も増えます。増えたときに同じ品質で処理されることのほうが、1枚あたりの仕上がりより重要だと考えました。
この記事の元
この記事は、「すいむいさんぽ」の制作で実際にやったことから書き起こしています。 方針そのものは運営方針にまとめています。