tomoima525's blog

Androidとか技術とかその他気になったことを書いているブログ。世界の秘密はカレーの中にある!サンフランシスコから発信中。

Androidで縦向き正方形撮影する時の苦労あれこれ(その2)

Androidで縦向き正方形撮影する時は色々面倒です。面倒なポイントと、解決方法について書いてみました。
今回はカメラで撮影した画像をinstagramなどのように正方形にする方法です。
カメラのプレビュー(surface view)と取得画像の撮影範囲が変わってしまう問題の解決方法を書いてます。

正方形の画像を取得する

正方形の画像を取得するためには、一旦Bitmapを作成してから、そのBitmapに対してBitmap#createBitmapを使って、正方形に切り取ります。
ですが、ここで問題になるのが、Surface viewとCamera Supported Sizeが異なる点です。
要は、プレビューで映したものと、実際に映した画像のサイズが異なってしまうわけです。(というか、自分は異なってしまいました。) 今使っている端末(Galaxy S3)だと以下のようなサイズ、縦横比率になります。

種類 サイズ 縦持ちで縦を1とした場合の横比率
Surface view 720*1230 0.58
Supported Camera Size 2488*3264(BitmapFactory#decodeByteArray でBitmap作成時) 0.76


で、このままだとカメラのプリビューで見えていたSurfaceViewよりも取得画像がより広い範囲を撮影してしまうことになってしまいます。図にすると以下のような具合です。


f:id:tomoima525:20140208131619p:plain


その回避策として、surface viewの横比率とSupported Camera Sizeの横比率の差分を調整しbitmapを再作成します。
コードは以下です。

Android code to make jpeg picture that fits with c ...

42-51行目で幅を調整しています。previewWidth,previewHeightはメンバー変数で、surfaceChanged()でwidth,heightを代入しています。

その他の部分について説明すると、

  • 17-24行目で opt.inJustDecodeBounds=trueとし、bitmapを作る前にまずサイズ情報を取得するようにしています。
  • Supported Camera SizeはBitmapFactory#OptionsのinSampleSizeで整数倍で出力サイズを変更できます。そのままBitmapに変換するとOutOfMemoryエラーが発生するので、必ずここで縮小します。
  • 29-52行目で一旦Bitmapを作り、それから正方形に整形しています。
  • 54-69行目で、getContentResolverを利用することで、端末に保存した画像を認識させます。

こんな具合です。 カメラのプレビュー(surface view)と取得画像の撮影範囲が変わってしまう問題は、Stack Over Flowでも質問上がっているのですが、解決方法が載ってなかったので、参考になればよいです。