2011-11-10 23 views
1

このコードで何が問題なのか教えていただけますか?Androidビットマップの操作

//bmp is a bitmap of already present image 
int width=bmp.getWidth(); 
int height=bmp.getHeight(); 
int rgbval[]=new int[width*height]; 
bmp.getPixels(rgbval, 0, width, 0, 0, width, height); 
rgbval=actual(rgbval); 
Bitmap bmp2=bmp.copy(Bitmap.Config.ARGB_8888,true); 
bmp2.setPixels(rgbval, 0, width, 0, 0, width, height); 

actual私はBMPのRGB値を操作するために作成した機能です。私はそれが正常に動作していることを確認したが、eclipseのデバッグ機能を使用することによって、bmp2のrgb値を回復しようとすると、私は操作された値を取得しません。

答えて

1

である私はこの問題は、いくつかのAndroidのバグが原因だと思います。私はビットマップのピクセルを操作し、私は正確に同じにピクセル値が必要でしたが、私はsetPixelsを使用してビットマップの完全なピクセルを設定すると動作しませんでした。私は使用して解決策を見つけた

index=0; 
for (int j = 0; j < height; j++) 
    for (int i = 0; i < width; i++) 
    { 
    destBitmap.setPixel(i, j, pixelvalues[index]); 

    } 

だから私は一度にすべてを一度に何かを設定するピクセル!

2

まず第一に、この答えを参照:だからAndroid Bitmap setPixel doens't work correctly? (set value, then read a different value)

を、あなたの元画像がアルファチャンネル(すなわち、hasAlphaは()がfalseを返す)を持っていない場合、それは自動的にRGB値を変換するようです事前に乗算された形式。 あなたはそれを体験していますか? bmp.hasAlpha()はfalseですか?

私は、hasAlpha()がtrueを返すビットマップとしてデフォルトのアンドロイドアイコンを使用してコードをテストしました。入出力カラー配列のアルファチャンネルは同一です。しかし、赤のチャンネルは、2304ピクセルのうちの15ピクセルに対して1または2だけオフになります。私は青または緑のチャンネルをチェックしなかった。私はこれが内部の丸め誤差だと思いますか?私は誰かが追加することがある場合に備えて、私が使用したかなり冗長で、テスト専用のコードを投稿しています。

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon); 

int width=bmp.getWidth(); 
int height=bmp.getHeight(); 
int rgbval[]=new int[width*height]; 
bmp.getPixels(rgbval, 0, width, 0, 0, width, height); 
int rgbval2[] = actual(rgbval); 

Bitmap bmp2=bmp.copy(Bitmap.Config.ARGB_8888,true); 
bmp2.setPixels(rgbval2, 0, width, 0, 0, width, height); 

int rgb2[] = new int[width*height]; 
bmp2.getPixels(rgb2, 0, width, 0, 0, width, height); 

int alpha1[] = new int[width*height]; 
int alpha2[] = new int[width*height]; 
int red1[] = new int[width*height]; 
int red2[] = new int[width*height]; 

for(int i=0; i<alpha2.length; ++i) { 
    alpha1[i] = Color.alpha(rgbval2[i]); 
    alpha2[i] = Color.alpha(rgb2[i]); 
    red1[i] = Color.red(rgbval2[i]); 
    red2[i] = Color.red(rgb2[i]); 

    if(red1[i]!=red2[i]) { 
     int a1 = alpha1[i]; 
     int a2 = alpha2[i]; 
     int r1 = red1[i]; 
     int r2 = red2[i]; 


     Log.e("E", String.format("a1: %d, a2: %d, r1: %d, r2: %d", a1, a2, r1, r2)); 
    } 
} 


private int[] actual(int rgb[]) { 
    int rgb2[] = new int[rgb.length]; 

    for(int i=0; i<rgb.length; ++i) { 
     rgb2[i] = Color.argb(Color.alpha(rgb[i]), Color.red(rgb[i])/2, 
         Color.green(rgb[i])/2, Color.blue(rgb[i])/2); 
    } 

    return rgb2; 
} 

、ここでLogCat出力

a1: 64, a2: 64, r1: 30, r2: 32 
a1: 64, a2: 64, r1: 30, r2: 32 
a1: 142, a2: 142, r1: 58, r2: 57 
a1: 142, a2: 142, r1: 58, r2: 57 
a1: 216, a2: 216, r1: 56, r2: 55 
a1: 216, a2: 216, r1: 56, r2: 55 
a1: 57, a2: 57, r1: 6, r2: 4 
a1: 59, a2: 59, r1: 6, r2: 4 
a1: 231, a2: 231, r1: 90, r2: 91 
a1: 216, a2: 216, r1: 95, r2: 94 
a1: 216, a2: 216, r1: 95, r2: 94 
a1: 217, a2: 217, r1: 57, r2: 58 
a1: 216, a2: 216, r1: 88, r2: 89 
a1: 199, a2: 199, r1: 66, r2: 67 
a1: 199, a2: 199, r1: 39, r2: 38 
+0

ur replyに感謝します。私のビットマップをチェックして、hasAlpha()がfalseであることが判明しました。私はそれを回避する方法を提案することができます。つまり、hasAlpha()をfalseにしているビットマップであっても自分のコードが動作するようにします。 –

+1

私のポストのリンクは、bmp.setHasAlpha(true)を呼び出します。しかし、その機能はAPIレベル12の後でしか利用できません。簡単な方法は、hasAlpha()がfalseの場合、読み取るピクセルのアルファ値を255に手動で設定することです。 –

+0

APIレベル7または8で動作するようにプロジェクトを設計しようとしていますので、setHasAlpha()を使用することはできません。アルファ値を自動的に255に設定するとどちらもうまく動作しないようですが、他の回避策があります –

関連する問題