【问题标题】:How do you get the RGB values from a Bitmap on Android?如何从 Android 上的位图中获取 RGB 值?
【发布时间】:2011-04-14 20:50:30
【问题描述】:

我想在 Android 上获取位图的 RGB 值,但目前还做不到。我的目标是获取位图每个像素的 RGB 值。 Android 或其他有什么特定功能吗?

我还想知道我需要colorMatrix() 函数吗?

这对我的项目非常重要。

【问题讨论】:

    标签: android image image-processing rgb android-bitmap


    【解决方案1】:

    Bitmap#getPixel(x, y) 返回一个 int,其中嵌入了颜色值和 alpha 值。

    int colour = bitmap.getPixel(x, y);
    
    int red = Color.red(colour);
    int green = Color.green(colour);
    int blue = Color.blue(colour);
    int alpha = Color.alpha(colour);
    

    【讨论】:

    • 一种非常简单的计算像素颜色值的方法。非常感谢!
    【解决方案2】:

    这可能有点晚了,但为了澄清与使用 &0xff 的混淆:

    在 Java 中,整数是 32 位的,因此每个像素的 (A)RGB 值被打包在 4 个字节中。 换句话说,在 ARGB_8888 模型中具有值 R(123)、G(93)、B(49) = FF7B 5D31 的像素。其中 Alpha = FF,R = 7B,G = 5D,B = 31。但这存储为 -8692431 的 int。

    因此,如您所知,要从 -8692431 中提取绿色值,我们需要将 5D 向右移动 8 位。这给出了 00FF 7B5D。所以,如果我们只取那个值,我们将留下 16743261 作为我们的绿色值。因此,我们用 0xFF 的掩码(相当于 0000 00FF)按位和该值将导致 00FF 7B5D 被“掩码”为 0000 005D。所以我们提取了 5D(或 93 十进制)的 Green 值。

    我们可以为每次提取使用相同的 0xFF 掩码,因为所有值都已被移位以将所需的两个字节公开为最低有效字节。因此之前建议的代码为:

    int p = pixel[index];
    
    int R = (p >> 16) & 0xff;
    int G = (p >> 8) & 0xff;
    int B = p & 0xff;
    

    如果更清楚,可以进行等价的操作:

    int R = (p & 0xff0000) >> 16;
    int G = (p & 0x00ff00) >> 8;
    int B = (p & 0x0000ff) >> 0;
    

    为了简洁,多余的0可以去掉,可以写成

    int R = (p & 0xff0000) >> 16;
    int G = (p & 0xff00) >> 8;
    int B = p & 0xff;
    

    但请注意,可以使用其他颜色模型,例如 RGB_555,它将每个像素存储为仅 2 个字节,RGB 通道具有不同的精度。所以你应该在执行提取之前检查你的位图使用的模型,因为颜色可能存储不同。

    【讨论】:

    • R、G 和 B 有什么理由不能是字节而不是整数?
    【解决方案3】:

    这就是我试图获得该价值的方式。使用bitmap.getPixel()获取对应的位图 整数数组。通过按位旋转操作,我们将得到 RGB 值。

                 int[] pix = new int[picw * pich];
                 bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
    
                 int R, G, B,Y;
    
                 for (int y = 0; y < pich; y++){
                 for (int x = 0; x < picw; x++)
                     {
                     int index = y * picw + x;
                     int R = (pix[index] >> 16) & 0xff;     //bitwise shifting
                     int G = (pix[index] >> 8) & 0xff;
                     int B = pix[index] & 0xff;
    
                     //R,G.B - Red, Green, Blue
                      //to restore the values after RGB modification, use 
     //next statement
                     pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
                     }}
    

    【讨论】:

    • 谢谢,但 &0xff 的含义是什么,因为 ff=11111111。 &(and operation) 得到与 11111 相同的数字,因为 0&1=1 1&1=1 一直都是。 int R = (pix[index] >> 16) 获取R就够了吗?
    • 谢谢,但 &0xff 的含义是什么,因为 ff=11111111。 &(and operation) 得到与 11111 相同的数字,因为 0&1=1 1&1=1 一直都是。 int R = (pix[index] >> 16) 获取R就够了吗?
    【解决方案4】:

    任意位图颜色处理

    您可以在此处阅读各种 Color 方法,这些方法将从像素 int 中提取颜色分量。

    您可能希望对位图应用过滤器,并返回一个字节数组。否则,您可以将此示例缩减为 for 循环并遍历生成字节数组的像素。

    private byte[] rgbValuesFromBitmap(Bitmap bitmap)
    {
        ColorMatrix colorMatrix = new ColorMatrix();
        ColorFilter colorFilter = new ColorMatrixColorFilter(
                colorMatrix);
        Bitmap argbBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(argbBitmap);
    
        Paint paint = new Paint();
    
        paint.setColorFilter(colorFilter);
        canvas.drawBitmap(bitmap, 0, 0, paint);
    
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int componentsPerPixel = 3;
        int totalPixels = width * height;
        int totalBytes = totalPixels * componentsPerPixel;
    
        byte[] rgbValues = new byte[totalBytes];
        @ColorInt int[] argbPixels = new int[totalPixels];
        argbBitmap.getPixels(argbPixels, 0, width, 0, 0, width, height);
        for (int i = 0; i < totalPixels; i++) {
            @ColorInt int argbPixel = argbPixels[i];
            int red = Color.red(argbPixel);
            int green = Color.green(argbPixel);
            int blue = Color.blue(argbPixel);
            rgbValues[i * componentsPerPixel + 0] = (byte) red;
            rgbValues[i * componentsPerPixel + 1] = (byte) green;
            rgbValues[i * componentsPerPixel + 2] = (byte) blue;
        }
    
        return rgbValues;
    }
    

    【讨论】:

    • 你好@Cameron Lowell Palmer,你能回答this的问题吗?我想我没有定义点击事件的边界。当我单击左上角时它可以工作,但是当我单击其他角时应用程序崩溃。请帮忙。
    • 感谢这就像一个魅力,并解释了如何提取 rgb vals 然后相应地处理它们。
    【解决方案5】:

    一个for语句少:D

    imagen.getPixels(pix, 0, picw, 0, 0, picw, pich);
    
        for (i = 0; i < pix.length; i++) {
            r = (pix[i]) >> 16 & 0xff;
            g = (pix[i]) >> 8 & 0xff;
            b = (pix[i]) & 0xff;
        }
    

    【讨论】:

      【解决方案6】:

      除了@Cobbles 的answer,您还可以使用Bitmap#getColor(x, y)Color 对象。

      for (int y = 0; y < bitmap.getHeight(); y++) {
          for (int x = 0; x < bitmap.getWidth(); x++) {
              Color color = bitmap.getColor(x, y);
      
              float red = color.red();
              float green = color.green();
              float blue = color.blue();
              float alpha = color.alpha();
      
              Log.d(TAG, String.format(
                      "(R, G, B, A) = (%f, %f, %f, %f)", red, green, blue, alpha
              ));
          }
      }
      

      使用上面的代码,您可以获得浮点 (0..1) RGBA 值。当您只想获取整数 (0..255) 值时,@Cobble 的方式相当简单(推荐)。虽然仍然有一种方法可以通过使用 Color#toArgb 来获取这个 Color 对象的整数值。

      for (int y = 0; y < bitmap.getHeight(); y++) {
          for (int x = 0; x < bitmap.getWidth(); x++) {
              int color = bitmap.getColor(x, y).toArgb();
      
              int red = Color.red(color);
              int green = Color.green(color);
              int blue = Color.blue(color);
              int alpha = Color.alpha(color);
      
              Log.d(TAG, String.format(
                      "(R, G, B, A) = (%3d, %3d, %3d, %3d)", red, green, blue, alpha
              ));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-12-04
        • 1970-01-01
        • 2014-12-25
        • 2015-06-10
        • 1970-01-01
        • 1970-01-01
        • 2017-03-16
        • 2010-09-13
        • 2010-10-01
        相关资源
        最近更新 更多