2011-01-07 32 views
6

次の問題があります。私はチャート作成プログラムを持っていますが、デザインは黒ですが、グラフ(サーバーからイメージとして取得)は明るいです(実際には赤、緑、白、黒、灰色の5色しか使用しません)。反転ビットマップの色

デザインの逆転に合わせると良い仕事ですが、唯一の問題は赤と緑が逆転していることです(緑 - >ピンク、赤 - >緑)。

2色以外のすべてを反転する方法はありますか、または反転後にその色を再ペイントする方法はありますか? これらの操作はどれくらいのコストがかかります(グラフの更新はかなり頻繁に行われるため)。事前:)

UPDATE

私は

for(int x = 0 ;x < chart.getWidth();x++) { 
     for(int y = 0;y < chart.getHeight();y++) { 
      final int replacement = getColorReplacement(chart.getPixel(x, y)); 
      if(replacement != 0) { 
       chart.setPixel(x, y, replacement); 
      } 
     } 
    } 

UnfortunetelyループにとsetPixel方法で色を交換しようとした中

おかげで、この方法は、(〜650ms)は、ある時間がかかりすぎますそれを行うより速い方法があり、setPixels()メソッドはより速く動作するでしょうか?

+3

あなたは次のように書いています:* "実際には5色しか使用しません" *しかし注意する必要があります。 「カラー」は、OSが「カラー」とみなすものではないと考えます。 たとえば、ARGB 32ビットでは、0xFF0000は "赤"のように見えます。しかし0xFF0001もそうです。しかし、彼らは2つの異なる色です。 – Gugussee

+0

ありがとうございますが、実際には5色しか使用していません。私はチャートが生成される場所にアクセスできるので、特別に非常に簡単にできます:) –

+0

OK私はあなたに答えます... – Gugussee

答えて

6

ははるかに高速です。配列を操作して、最後にsetPixelsを呼び出してください。そのような

何か:

int length = bitmap.getWidth()*bitmap.getHeight(); 
int[] array = new int[length]; 
bitmap.getPixels(array,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 
for (int i=0;i<length;i++){ 
// If the bitmap is in ARGB_8888 format 
    if (array[i] == 0xff000000){ 
    array[i] = 0xffffffff; 
    } else if ... 
    } 
} 
bitmap.setPixels(array,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 
+0

ありがとう、私は実際に似たメソッドを試みたが、IntBuffer、 BitmapのcopyPixelsToBuffer()を使用していましたが、それでもまだ250msかかりました。 あなたの方法は〜100msかかります –

2

BufferedImageとして入手可能な場合は、そのラスターにアクセスして自由に編集できます。あなたは一度だけgetPixelsを呼び出すことにより、int配列内に画像データをコピーして、ループ内の任意の関数を呼び出さない場合は、ビットマップの操作

WritableRaster raster = my_image.getRaster(); 

// Edit all the pixels you wanna change in the raster (green -> red, pink -> green) 
// for (x,y) in ... 
// raster.setPixel(x, y, ...) 

my_image.setData(raster); 
+0

ありがとう。私はすぐにそれをchetckすぐに –

+0

うーん..私はアンドロイドがBufferedImage、またはWritableRasterを持っていないと思います:( –

+0

ああ、申し訳ありません、これはJavaソリューションです...私はそれもアンドロイドで利用できると思った...私の悪い。 – dagnelies

2

OK、あなたが本当に唯一のそれは非常に簡単だ5色を使用していることがわかります。

パフォーマンスについては、私はAndroidについてはわかりませんが、を使用するJavaでは、setRGBはデータバッファを取得してint []に直接書き込むよりもかなり遅いことを伝えています。

私はあなたのアイデアを与えるために、 "驚くほど遅く" を書き込むと、OS X 10.4上で、次のコード:(!):

for (int x = 0; x < width; x++) { 
    for (int y = 0; y < height; y++) { 
     array[y*width+x] = 0xFFFFFFFF; 
    } 
} 

for (int x = 0; x < width; x++) { 
    for (int y = 0; y < height; y++) { 
     img.setRGB(x,y,0xFFFFFFFF); 
    } 
} 

が100倍よりも遅くなることができますあなたは正しく読む:100時間。 Core 2 Duo/Mac Mini/OS X 10.4で測定しました。

(もちろん、あなたが最初の根底にあるのint []配列へのアクセスを取得する必要がありますが、うまくいけば、これは難しいことではありません)

私は問題がforループ2ではないことを十分に強調することはできません。どちらの場合も、最適化されていないループと同じです。だから、ここで問題となっているのは本当にsetRGBです。

私はAndroid上で動作するのか分かりませんが、うまくいくものが必要な場合はおそらくsetRGBを取り除くべきでしょう。

2

すぐに、AvoidXfermodeを使用して、変更したい色だけを再描画することができます。希望する色に切り替えることができます。あなたはこのような何かを実行する必要があります。

// will change red to green 
Paint change1 = new Paint(); 
change1.setColor(Color.GREEN); 
change1.setXfermode(new AvoidXfermode(Color.RED, 245, AvoidXfermode.Mode.TARGET)); 

Canvas c = new Canvas(); 
c.setBitmap(chart); 
c.drawRect(0, 0, width, height, change1); 

// rinse, repeat for other colors 

あなたはAvoidXfermodeのために公差でプレーする必要があるかもしれませんが、それはあなたがピクセル単位の計算よりもはるかに高速欲しいものを行う必要があります。また、あなたのチャートイメージがARGB8888モードであることを確認してください。デフォルトでは、AndroidはRGB565モードの画像で動作する傾向があります。使用したい色の計算を混乱させる傾向があります。画像がARB8888モードの両方にあることを確認するには、Bitmap chart = chartFromServer.copy(Config.ARGB_8888, true); Xfermodeを設定します。

明確化は:

// changes green to red 
Paint change1 = new Paint(); 
change1.setColor(Color.GREEN); 
change1.setXfermode(new AvoidXfermode(Color.RED, 245, AvoidXfermode.Mode.TARGET)); 

// changes white to blue 
Paint change2 = new Paint(); 
change2.setColor(Color.BLUE); 
change2.setXfermode(new AvoidXfermode(Color.WHITE, 245, AvoidXfermode.Mode.TARGET)); 

// ... other Paints with other changes you want to apply to this image 

Canvas c = new Canvas(); 
c.setBitmap(chart); 
c.drawRect(0, 0, width, height, change1); 
c.drawRect(0, 0, width, height, change2); 
//... 
c.drawRect(0, 0, width, height, changeN); 
:あなたはちょうどあなたがそうのように変更する適切な色で他の塗料を作成しなければならない、あなたはすべての繰り返しの画像を再ロードする必要がないと、他の色を変更するには
+0

確かに高速ですが、どのようにして一度にすべての色を変更できますか?私は2色(白、黒)しか持っておらず、逆にしたい場合、すべての黒のピクセルを白にした後、すべての白のピクセルを黒にすることはできません。黒に。ですから、私は完全に黒いイメージを得るでしょう。 私はある種のバッファーカラーを白黒に使用することを考えましたが、それには多くの時間がかかりませんか? また、これを複数回実行すると、最後の変更のみが反映されます。 –

+0

中間色のステップを必要としないためには、*ほとんど*白*黒*緑*どんな色や小さな公差でも使用できるはずです。 '0xFFFF0000'と' 0xFF00FF00'という2つの色を切り替えたい場合は、Xfermodeで2つのペイントを設定できます.1つは '0xFFFF0000' - >' 0xFF00EE00'です(*ルックスは緑ですが、 '0xFF00FF00'、* true * green)ではなく、' 0xFF00FF00' - > '0xFFFF0000'です。重要な点は、2つのカラー変更のために別々のペイントを設定し、正しい順序でイメージに適用する必要があることです。 –

+0

私は参照してください。私はそれを正しく取得すると、1つの色を変更することがありますが18ミリメートル、5色を変更する〜90、右がかかるでしょう。 これは実際には非常に高速なソリューションですが、明日10色を使用すると、ピクセル単位での置換よりも時間がかかります。 一度に複数の変更を適用する方法はありませんか? –

関連する問題