2012-01-04 9 views
1

私はいくつかの絵やimage_newとソースビットマップであるimage_source持っている - 一時的なビットマップJava。ビットマップ上のすべてのピクセルを実行して処理する最速の方法は何ですか?

私はimage_sourceはアナグリフバックグラウンド層とすることになり、このコードは、実行します。そして、

int [] pixel = {0x0, 0x0, 0x0}; 
int [] image_params = {image_source.getWidth() - 2 * anaglyph_amplitude, image_source.getHeight()}; 
Bitmap image_new = Bitmap.createScaledBitmap(image_source, image_params[0], image_params[1], false); 
for(int i = 0; i < image_params[0]; ++i) 
    for(int j = 0; j < image_params[1]; ++j) { 
     pixel[0] = image_source.getPixel(i, j); 
     pixel[1] = image_source.getPixel(i + 2 * anaglyph_amplitude, j); 
     pixel[2] = pixel[0] + pixel[1] % 0x10000 - pixel[0] % 0x10000; 
     image_new.setPixel(i, j, pixel[2]); 
    } 
image_source = Bitmap.createBitmap(image_new); 
image_new = null; 

image_sourceは(キャンバスに描かれているがキャンバスへの描画は利用できません)。

問題は、このプログラマーがスマートなAndroidデバイスで1000x1000サイズの画像を処理するのに約5秒かかることです。

ビットマップピクセルを実行する他の方法はありますか?

+0

私は画像処理中に同じ問題があります。処理するには時間がかかります。私はscollbarで処理したい(バーの進捗状況の変更を求める)。 –

+0

以下の回答を参照してください。しかし、要約すると、getPixels()を使用して一度に多数のピクセルを取得することです。 – user949300

答えて

0

スニペットコードのパフォーマンスが向上しています。私はそれがあなたのために十分であるとは確信していません。

まず変更

pixel[2] = pixel[0] + (pixel[1] & 0xFFFF) - (pixel[0] & 0xFFFF); 

代わりの

pixel[2] = pixel[0] + pixel[1] % 0x10000 - pixel[0] % 0x10000; 

-

pixel[1] = image_source.getPixel(i + (anaglyph_amplitude<<1), j); 

代わりの

pixel[1] = image_source.getPixel(i + 2 * anaglyph_amplitude, j); 
+0

目に見える違いはありません。私は実験を行いました:私は、 'pixel [0] = image_source.getPixel(i、j);'をループ内のコード全体に置き換えました。結果は同じでした – Finesse

+0

素早く1回の操作で全ピクセルカラーのアライを得ることができましたか? – Finesse

+0

リアルタイムでコードの一部を消費することを診断します。ループ前、ループ後、およびcreateBitmap()の後にタイムスタンプを出力します。 –

0

もう一つのマイナーな微調整。内部ループでは、ピクセル[1]などの配列を使用する理由はありません.3つのint、p0、p1、およびp2を持ちます。

EDITは、私はスイングよりもアンドロイドであまり知られてる

を追加しましたが、私はAndroidのビットマップは、ラスターに似た「私の時間の画素の束を得る」方法を持っていることを期待していました。します。

私はあなたが利用可能なメモリを持っている場合は、一度にすべて1,000,000を取得しますが、ビットマップ方式にjavadocs link here

public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height) 

を使用するべきだと思います。

+0

getPixelのみのループには多くの時間がかかります – Finesse

+0

@Finesse - 編集を参照してください。getPixel()を1000 x 1000回呼び出すのではなく、一度にすべてのピクセルを取得するAPI呼び出しが見つかりました。 – user949300

0

2 * anaglyph_amplitudeの計算をキャッシュすることができるため、各繰り返しで計算する必要はありません。

+0

コンパイラはすでにこれを行っています。 – user949300

+0

@ user94ホットスポットc2で?確かに、しかしあなたはアンドロイドのJITがどれほど良いか考えていますか? (そしてそれはandroid2.2 +のリリースを前提としています)CSEを実行するかどうかは考えられません。 – Voo

0

解決策は次のとおりです。ピクセルの配列を取得してそれを処理します。

int [] pixel = {0x0, 0x0, 0x0}; 
int [] pixels_old, pixels_new; 
int [] params = {image_source.getWidth(), image_source.getHeight()}; 
int [] image_params = {image_source.getWidth() - 2 * anaglyph_amplitude, image_source.getHeight()}; 
pixels_old = new int[params[2] * params[3]]; 
pixels_new = new int[image_params[0] * image_params[1]]; 
image_source.getPixels(pixels_old, 0, params[2], 0, 0, params[2], params[3]); 
image_source = null; 
for(int i = 0; i < image_params[0]; ++i) 
    for(int j = 0; j < image_params[1]; ++j) { 
     pixel[0] = pixels_old[i + j * params[2]]; 
     pixel[1] = pixels_old[i + (anaglyph_amplitude<<1) + j * params[2]]; 
     pixel[2] = pixel[0] + (pixel[1] & 0xFFFF) - (pixel[0] & 0xFFFF); 
     pixels_new[i + j * image_params[0]] = pixel[2]; 
    } 
pixels_old = null; 
image_source = Bitmap.createBitmap(pixels_new, image_params[0], image_params[1], Bitmap.Config.ARGB_8888); 
pixels_new = null; 
+0

良い!どれくらい早いですか? getPixels()を見つけてうれしいです。 – user949300

関連する問題