こんにちは、 rightgo09 です。
Go 言語の disintegration/imaging を使った JPEG の画像処理をしてみます。
Exif の Orientation
JPEG 画像の Exif 情報には、 Orientation (方向)という項目が存在することがあり、この Orientation を適用しないと期待通りの方向に見えません。
Orientation については、こちらの Qiita の記事がわかりやすかったです。ありがとうございます。 qiita.com
iPod touchで縦向きに撮った写真が、 Orientation: 6 (反時計回りに90度回転) となっていたので、この縦長の写真を使って確認してみます。
Orientation がビューワに認識されている場合
Orientation がビューワに認識されていない場合
disintegration/imaging を使ってみる
画像の幅と高さ
Orientation が 6 (反時計回りに90度回転) の画像の幅と高さを確認してみます。
package main import ( "fmt" "github.com/disintegration/imaging" ) func main () { path := "./photo.jpg" srcImage, err := imaging.Open(path) if err != nil { panic(err) } point := srcImage.Bounds().Size() fmt.Printf("width: %d, height: %d\n", point.X, point.Y) }
$ go run main.go width: 3264, height: 2448
幅の方が長い、横長の画像として認識されています。
しかし、 v1.5.0 からは、 Open() に AutoOrientation フラグを指定できるようになったので、これを利用してみます。
srcImage, err := imaging.Open(path, imaging.AutoOrientation(true)) if err != nil { panic(err) } point := srcImage.Bounds().Size() fmt.Printf("width: %d, height: %d\n", point.X, point.Y)
$ go run main.go width: 2448, height: 3264
高さの方が長い、縦長の画像として認識されました。
回転処理とリサイズ処理
幅 800px のサムネイルを作成してみます。
srcImage, err := imaging.Open(path) if err != nil { panic(err) } f, err := os.Create("./thumbnail.jpg") if err != nil { panic(err) } // 幅を800pxにする thumbnailImage := imaging.Resize(srcImage, 800, 0, imaging.Lanczos) if err := imaging.Save(thumbnailImage, f.Name()); err != nil { panic(err) } f.Close()
Orientation を無視して、画像が作成されてしまいました。 この作成された画像は Orientation が削除されているため、mac のプレビュー.app でも期待した方向になっていません。
ということで、サムネイル作成などのリサイズ処理をする前には、やはり Orientation を気にする必要がありました。 Orientation が 6 のときは、270度反時計回りに回転させます。
if orientation == 6 { srcImage = imaging.Rotate270(srcImage) }
しかしこちらの場合も、Open() に AutoOrientation フラグをつけておくと、この回転処理自体が不要になりました。
srcImage, err := imaging.Open(path, imaging.AutoOrientation(true)) if err != nil { panic(err) } f, err := os.Create("./thumbnail.jpg") if err != nil { panic(err) } // 幅を800pxにする thumbnailImage := imaging.Resize(srcImage, 800, 0, imaging.Lanczos) if err := imaging.Save(thumbnailImage, f.Name()); err != nil { panic(err) } f.Close()
以上です。