--/--/-- (--) スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スポンサー広告 |


2011/11/10 (Thu) Androidプログラミング5 画像編集「モノクロフィルタのソースコード」

 前回紹介したノイジーなモノクロフィルタのソースコード。撮影したBitmapを引数で受け取り変換したBitmapを戻すメソッドです。変換処理は、例えばVGA(640x480)サイズの写真の場合、1ピクセルずつカラーデータを取り出し、そのデータを書き換えて写真に戻すという作業を約31万回繰り返します。今回はARGB_8888というフルカラーのデータとして扱っていますが、メモリ不足になる場合はRGB_565などでも問題ないと思います。

 ARGB_8888とは、左から透明度(Α)、赤(R)、緑(G)、青(B)で各8ビット(256段階)の色データを持つ形式です。白を黒に変換するというフィルタの場合、ARGB(255,255,255,255)をARGB(255,0,0,0)に置き換えることになります。

ソースの解説

①通常のBitmapは編集が不可能なため、Bitmapをコピーしてmutable(編集可能)なBitmapを生成します。ここで一時的にメモリ上にビットマップが2枚存在することになるため、解像度の大きな画像を使うとOut of Memory Errorで落ちます。例外ではなくエラーなので回避処理が存在せず、現状フィルタ処理をサービスでプロセスを分け、エラーになってもメインのアクティビティが巻き込まれないようにしています。

②Bitmapの色データをint配列にまとめて読み込みます。getPixel()メソッド、setPixel()メソッドで1ループごとに色の置換をしていっても良いのですが、処理にかかる時間が長くなるためまとめて取得しまとめて配置するようにしています。

③RGBからグレースケールを求める計算式はいくつかありますが、ここではもっともシンプルなRGBの総和を3で割った数値をRGBに入れる方法を採っています。

④コントラストの計算式です。1.9の部分を変更することでコントラストが変化します。ここではかなり強めにしています。

⑤ノイズを載せるためにランダムで色を変化させます。

⑥このフィルタでは乗算しかしていないのでこのif文は不要ですが、RGBの値が「0-255」の範囲外になると色が反転してしまうので、はみ出した部分に対する処理が必要になることがあります。

  public static Bitmap monoChrome(Bitmap bitmap, Random rnd) {

Bitmap editBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); ・・・①
int width = editBitmap.getWidth();
int height = editBitmap.getHeight();
int pixels[] = new int[width * height];
int red, green, blue, gray, ran, pixel;
editBitmap.getPixels(pixels, 0, width, 0, 0, width, height); ・・・②

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixel = pixels[x + y * width];
red = Color.red(pixel);
green = Color.green(pixel);
blue = Color.blue(pixel);
gray = (red + green + blue) / 3;

// 輝度を求める公式
// gray = (77 * red + 28 * green + 151 * blue) / 256; ・・・③

gray = (int) ((gray - 128) * 1.9 + 128); ・・・④

if (gray > 225) {
gray *= 0.8;
} else if (gray < 30) {
gray *= 1.2;
}
if (gray > 255) {
gray = 255;
} else if (gray < 255) {
ran = rnd.nextInt(6); ・・・⑤
if (ran == 1) {
gray *= 0.96;
} else if (ran == 2) {
gray *= 0.92;
} else if (gray < 220 && ran == 3) {
gray *= 0.96;
} else if (gray < 220 && ran == 4) {
gray *= 0.92;
} else if (gray < 180 && ran == 5) {
gray *= 0.96;
} else if (gray < 180 && ran == 6) {
gray *= 0.92;
}
if (gray < 0)
gray = 0; ・・・⑥
}
pixels[x + y * width] = Color.rgb(gray, gray, gray);
}
}
editBitmap.setPixels(pixels, 0, width, 0, 0, width, height); ・・・②
return editBitmap;
}

プログラミング | trackback(0) | comment(0) |


<<【Android】AlertDialogのカスタマイズ(選択肢を作る場合) | TOP | ルフロントレイン>>

comment











管理人のみ閲覧OK


trackback

trackback_url
http://kononushi.blog46.fc2.com/tb.php/642-59e0e58c

| TOP |

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。