在 android 中更快地获得 RGB

get RGB faster in android

以下是我获取 RGB 颜色并在位图(另一个位图)中的颜色为绿色时更改临时(位图)颜色的方法。但是性能很差,用了大约 20 秒或更长时间。我有什么方法可以改进它吗?非常感谢。

 //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);

我想我要做的是确定每个像素的大小。最有可能是 32 位 ARGB。所以你有一个 WxH 多头数组。遍历该数组,如果值是 G = 255 的值,则替换它。我也会忽略 ALPHA 通道

有几种方法可以加快速度。让我们从最简单的开始:


float[] hsv = new float[3];

使用 new 在堆上分配内存,这很慢而且对缓存不友好(并且需要事后释放(取决于语言,这可能是自动的))。您可以(重新)使用本地 float[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]);

没有变化的像素不需要设置。因此,您可以将 temp.setPixel 移动到 if 块内。实际上 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() 可能会很慢(同样取决于语言)。最好像处理二维数组一样直接处理像素数据。大多数语言都提供了获取指针或访问原始像素数据的功能。