「ジオラマカメラ」作成にあたり、今回は画質の勉強です。
よく家電屋さんでデジカメなどを見ると「○○○万画素!」と書かれています。
恥ずかしながら数字が大きい方が良い!という知識レベルでした。
そんな自分なので、まずはプログラムを書く前に単語の整理です。
画質を表す用語
画素:ピクセルのことでよくドットともいわれる点のことですね。
画素数:1枚の画像に含まれる画素(ピクセル)の数
解像度:1インチに対する画素数(dot per inch:dpi)
写真などを印刷した場合、用紙のサイズは同じため1枚の写真に含まれる画素数が多いほど、きめ細やかな写真になります。しかし、Webで表示する場合、画像のサイズはピクセルなので、そのまま表示するとかなり大きな画像になってしまう場合があります。
Androidによる画像の読み込み
drawableフォルダに保存されている以下の画像をAndroidで読み込んでみます。
Bitmap bmp = BitmapFactory.decodeResource( getResources(), R.drawable.jellybean); // (1) int width = bmp.getWidth(); // (2) int height = bmp.getHeight(); // (2) int size = width * height; int px[] = new int[size]; // (3) int offset; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { offset = x + (y * width); px[offset] = bmp.getPixel(x, y); // (4) } }
(1) 画像の読み込みにはBitmapFactoryクラスを利用します。
BitmapFactoryクラスを利用することで画像の読み込みが簡単に作成されます。
(2) 読み込みが完了した画像はBitmap型に保管さ、getWidth()やgetHeight()メソッドから、
対象画像のサイズを取得しています。
(3) 読み込んだ画像を反映するための配列を作成します。
縦と横のピクセル数を掛けて画素数を算出します。
その画素数で配列を用意します。
(4) 座標を指定してピクセル情報を取得
読み込みの性能改善
上記の方法でも画像の読み込みは可能ですが、for文の二重ループのため画素数が多くなればなるほど遅くなります。
そこでgetPixel()関数ではなく、getPixels()関数を利用する事で性能がアップします。
Bitmap bmp = BitmapFactory.decodeResource( getResources(), R.drawable.jellybean); int width = bmp.getWidth(); int height = bmp.getHeight(); int size = width * height; int px[] = new int[size]; bmp.getPixels(px, 0, width, 0, 0, width, height); // (1)
画像の読み込み、格納用の配列取得は変わりません。
(1) ピクセルの取得開始位置やサイズを指定する事で一度に取得出来ます。
実際にどれぐらいの性能性あるかというと以下のとおりでした。
・800pix×600pix(48万画素)
getPixel → 2879ms
getPixels → 131ms
・400pix×400pix(16万画素)
getPixel → 1065ms
getPixels → 107ms
16万画素では10倍の差が、48万画素になると20倍の差が出ています。
しかし、getPixels()関数では30msとほとんど差が状態でした。
今後の課題
小さな画像ならばこれで問題ないのですが、大きなサイズ(数MB)の画像を読み込む場合、メモリの負担が高くなってしまいます。
PCならばあまり気にしなくてもよいかもしれませんが、今回はAndroidスマートフォンが対象なので、見直しは必要ですね。
ここは順次調べてアップしています。
※画像処理に関しては勉強を始めたばかりです。記載誤りや補足などありましたらコメントいただけるとうれしいです。
この記事のトラックバック用URL