37

我想在 Android 上获取位图的 RGB 值,但到目前为止我还不能这样做。我的目标是获取位图每个像素的 RGB 值。是否有适用于 Android 或其他任何特定功能?

另外我想知道我需要colorMatrix()功能吗?

这对我的项目非常重要。

4

6 回答 6

35

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);
于 2014-11-16T17:57:47.883 回答
34

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

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

因此,如您所知,要从 -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 通道具有不同的精度。因此,您应该在执行提取之前检查您的位图使用的模型,因为颜色可能以不同的方式存储。

于 2012-11-27T12:06:46.650 回答
18

这就是我试图获得该价值的方式。使用 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;
                 }}
于 2011-04-14T20:55:55.273 回答
8

任意位图颜色处理

您可以在此处阅读各种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;
}
于 2017-01-20T10:05:15.587 回答
7

一个声明少: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;
    }
于 2011-10-11T04:59:05.927 回答
0

除了@Cobbles 的答案,您还可以使用Bitmap#getColor(x, y)and 一个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
        ));
    }
}

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

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
        ));
    }
}
于 2022-01-20T07:08:10.413 回答