最近、 「デジカメで撮影した画像がプレビューでは正常に表示されるのに、いざアップロードすると横向きになる。」という問題にぶつかったのですが、その際に調べたことならびに解決策をまとめてみます。
結論
先に結論を書いておくと、Exif の orientation に起因する問題でした。
アプリケーションは Rails で、アップロード周りは CarrierWave + MiniMagick を使っているので、以下のようなワークアランドを入れました。
config/initializers/carrierwave.rb
module CarrierWave
module MiniMagick
def fix_exif_rotation
manipulate! do |img|
img.auto_orient
img = yield(img) if block_given?
img
end
end
end
end
app/uploaders/your_image_uploader.rb
class YourImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process :fix_exif_rotation
snip...
end
原因調査
本問題を最初に発見した時は、なかなか原因に当たりがつきませんでした。
というのも、ブラウザで見ると90度回転しているにも関わらず、URL直接指定すると正常に表示されており、またダウンロードしてプレビューアプリで見ても正常に表示されていたからです。
CSSに原因があるのではないかと Inspector で調べるも、怪しいところは発見されず悶々としていたところ、同僚エンジニアが https://twitter.com/pastak/status/436793706377535488 という tweet を教えてくれ、これが解決の糸口となりました。
実際に identify コマンドで確認すると、orientation が 6(時計回りに90度回転)となっていることが確認できました。
$ identify -vervose file-name.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 800x600+0+0
snip...
exif:Orientation: 6
exif:ResolutionUnit: 2
解決策
今回はかなり一般的な問題(自身は知らなかったわけですが^^)だったので、解決策を見つけるのはさほど難しくありませんでした。書いたコードは冒頭の通りです。
関連する CarrierWave のコードとドキュメントも読んだので、ここに記載しておきます。
- http://www.rubydoc.info/github/jnicklas/carrierwave/CarrierWave/MiniMagick
- https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/processing/mini_magick.rb
まとめ
Exifについて詳しくなかったので勉強になりました。同時に、引き出しをたくさん持っていたほうが問題解決スピード早いよね、ということも改めて実感しました。
最後に、解決策を探すにあたって参考にしたサイトを挙げておきます。