2017-02-28 53 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