【问题标题】:How to iterate through pixels in a more efficient way?如何以更有效的方式遍历像素?
【发布时间】:2020-04-12 00:12:31
【问题描述】:

我正在获取图像并将其转换为位图。为了检查像素的颜色是否介于两个值之间,我遍历给定位图的每个像素。我创建一个新的位图,如果像素介于这些值之间,则更改像素,然后在新位图上设置.Pixel(),或者将像素保持原样并将其设置在新位图上。我将 Bitmap.Config 从 ARGB-8888 减少到 RGB_565,但它仍然慢得令人难以置信,并在调试中显示“应用程序可能在其主线程上做了太多工作。”

有没有更好的方法来做到这一点并使应用程序更快?

 width = bitmap.getWidth();
        heigth = bitmap.getHeight();
        Bitmap newBitmap = Bitmap.createBitmap(width, heigth, Bitmap.Config.RGB_565);

        for(int x = 0; x < width; x++){
            for(int y = 0; y < heigth; y++){
                int pixel = bitmap.getPixel(x,y);
                float[] pixelHue = getHsv(pixel);
                if(pixelHue[0] > 170 && pixelHue[0] < 250 ){
                 //Change the Pixel
                    pixelHue[0] = pixelHue[0] - 17;
                    int newColor = setRgb(pixelHue);
                    newBitmap.setPixel(x, y, newColor);
                }
                else{
                      //leave the Pixel as it is
                    newBitmap.setPixel(x, y, pixel);
                }

            }
        }
        return newBitmap;
    }



private float[] getHsv (int pixel){
         int a = Color.alpha(pixel);
         int r = Color.red(pixel);
         int g = Color.green(pixel);
         int b = Color.blue(pixel);
         float[] hsv = new float[3];
         Color.RGBToHSV(r, g, b, hsv);
        return hsv;
    }


private int setRgb (float[] hsv){
        int rgb;
        rgb = Color.HSVToColor(hsv);
        return rgb;
    }





【问题讨论】:

  • 为什么要在主线程上做呢?
  • Idk,我不是编程专家,到目前为止还没有使用过线程。我该怎么办?
  • 使用AsyncTask
  • 什么是getHsv?像这样的紧密循环中的内存分配可能是一个问题
  • @Joni 这是一种我将 rgb 转换为 hsv 并返回色调、饱和度和值的方法。检查色调值是否在两个值之间

标签: java android


【解决方案1】:

但我需要检查像素颜色的色调值以指示颜色是否在我的范围内

正确,但您不需要每次都将像素转换为 HSV 值。您可以进行一次转换,然后存储结果。

所以你的代码的基本结构可能是这样的:

HashMap<Integer, Integer> pixels = new HashMap<Integer, Integer>(); // instance variable of your class

for(…)
{
    for (…)
    {
        int pixel = bitmap.getPixel(x,y)
        int pixelHue = getPixelHue( pixel );
        newBitmap.setPixel(x, y, pixelHue);
    }
}

…

private int getPixelHue(int pixel)
{
    Integer pixelHue = pixels.get(pixel);

    if (pixelHue == null) // you haven't attempted to convert this pixel yet
    {
        float[] hsv = getHsv(pixel);

        if(hsv[0] > 170 && hsv[0] < 250 )
        {
            // Change the hue value of the hsv color
            hsv[0] = hsv[0] - 17;
            pixelHue = setRgb(hsv); // conversion done
        }
        else
        {
            pixelHue = pixel; // no conversion needed
        }

        pixels.put(pixel, pixelHue); // store result so we don't need to reconvert
    }

    return pixelHue;
}

所以 HashMap 原本是空的。当您处理一个唯一颜色的像素时,如果需要,您将进行 HSV 转换和色调转换,并将结果存储在 HashMap 中。下次处理此像素颜色时,无需重复转换过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    相关资源
    最近更新 更多