2017-02-28 24 views
1

以下是我獲得eh RGB顏色並在位圖(另一個位圖)中的顏色爲綠色時在temp(位圖)中更改顏色的方法。但表現相當糟糕,時間大約在20秒或更長。有什麼方法可以改善它嗎?非常感謝你。在android中獲取RGB更快

//get the green color of each pixel 
    color = new int[bitmap.getWidth()][bitmap.getHeight()]; 
    for (int x = 0; x < bitmap.getWidth(); x++) { 
     for (int y = 0; y < bitmap.getHeight(); y++) { 
      color[x][y] = temp.getPixel(x, y); 
      if (bitmap.getPixel(x, y) == Color.GREEN) { 
       color[x][y] = temp.getPixel(x, y); 
       float[] hsv = new float[3]; 
       Color.RGBToHSV(Color.red(color[x][y]), Color.green(color[x][y]), Color.blue(color[x][y]), hsv); 
       hsv[0] = 360; 
       color[x][y] = Color.HSVToColor(hsv); 
      } 
      temp.setPixel(x, y, color[x][y]); 
     } 
    } 

imageView.setImageBitmap(temp); 

更新:

intArray = new int[bitmap.getWidth()*bitmap.getHeight()]; 
        bitmap.getPixels(intArray,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 

    int[] tempArray = new int[bitmap.getWidth()*bitmap.getHeight()]; 
     temp.getPixels(tempArray,0,temp.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight()); 

    //get the color of each pixel 
    color = new int[bitmap.getWidth()][bitmap.getHeight()]; 
    for (int x = 0; x < bitmap.getWidth(); x++) { 
     for (int y = 0; y < bitmap.getHeight(); y++) { 
      if (intArray[x + y * bitmap.getWidth()] == Color.BLUE) { 
       float[] hsv = new float[3]; 
       Color.RGBToHSV(Color.red(tempArray[x + y * bitmap.getWidth()]), Color.green(tempArray[x + y * bitmap.getWidth()]), Color.blue(tempArray[x + y * bitmap.getWidth()]), hsv); 
       hsv[0] = 360; 
       tempArray[x + y * bitmap.getWidth()] = Color.HSVToColor(hsv); 

      } 
     } 
    } 

    temp.setPixels(tempArray,0,temp.getWidth(),0,0,temp.getWidth(),temp.getHeight()); 

    imageView.setImageBitmap(temp); 

回答

1

有幾種方法可以讓這個速度更快。讓我們先從最簡單的:


float[] hsv = new float[3];

使用new分配在堆上,這是緩慢的,而不是高速緩存友好(並且需要之後釋放的內存(取決於語言,這可能是自動))。你可以(重新)使用本地浮點數[3]。


color[x][y] = temp.getPixel(x, y); 
    if (bitmap.getPixel(x, y) == Color.GREEN) { 
     color[x][y] = temp.getPixel(x, y); 

不需要做第二temp.getPixel()(這可能會很慢)在這裏。該數據已在color[x][y]


color[x][y] = temp.getPixel(x, y); 
    if (bitmap.getPixel(x, y) == Color.GREEN) { 
     // ... 
    } 
    temp.setPixel(x, y, color[x][y]); 

無需設置像素,如果它沒有改變。因此,您可以在if區塊內移動temp.setPixel。而實際上color[x][y] = temp.getPixel(x, y);也可以去if塊內(或只是刪除外一個,因爲同樣已經是if塊內)


color = new int[bitmap.getWidth()][bitmap.getHeight()]; 

首先,你可能想在這裏使用unsigned int,但實際上你不需要這第三個數組。您可以改用本地unsigned int color變量。


for (int x = 0; x < bitmap.getWidth(); x++) { 
    for (int y = 0; y < bitmap.getHeight(); y++) { 

根據不同的語言,你可能想扭轉循環的爲了更多的緩存友好(見this)。確定最簡單的方法是使用這兩個訂單進行快速測試。


getPixel()setPixel()可以(也取決於語言)是緩慢的。像在二維數組上一樣直接處理像素數據會更好。大多數語言都提供了獲取指針或訪問原始像素數據的功能。

+0

謝謝你的回覆。 像在二維數組上一樣,直接處理像素數據會更好。 < - 我對這個很感興趣,請介紹一下我的進一步解釋嗎? – ng2b30

+0

@ ng2b30而不是使用'getPixel()'和'setPixel()',你可以直接訪問像素數組,這要快得多:byte [] pixels =((DataBufferByte)bufferedImage.getRaster()。getDataBuffer()) .getData();' - 參見http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image –

+0

我有一個問題。我怎樣才能從畫廊加載一個PNG圖像,以改變它是一個get bufferedImage?謝謝。 – ng2b30

0

我想我會做的是確定每個像素的尺寸。最有可能的是32位ARGB。所以你有一堆WxH多頭。循環訪問該數組,如果值是G = 255,則將其替換。我也會忽略ALPHA頻道

+0

你介意給我一些例子嗎?謝謝。 – ng2b30