在 Android 上如何从位图获取 RGB 值?

发布于 2024-11-01 15:18:11 字数 154 浏览 9 评论 0 原文

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

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

这对我的项目非常重要。

I want to get RGB values of a Bitmap on Android but I can't do this so far. My aim is to obtain RGB values for each pixel of a Bitmap. Is there any specific function for Android or anything else?

Also I wonder that do I need colorMatrix() function?

It is very important for my project.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

飘过的浮云 2024-11-08 15:18:11

这可能有点晚了,但为了消除使用 &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)的绿色值。

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

This may be slightly late, but to clear up the confusion with the use of &0xff:

In Java ints are 32 bits, so the (A)RGB values for each pixel are packed in 4 bytes.
In other words, a pixel with the values R(123), G(93), B(49) = FF7B 5D31 in the ARGB_8888 model. Where Alpha = FF, R = 7B, G = 5D, B = 31. But this is stored as an int as -8692431.

So, to extract the Green value from -8692431, we need to shift the 5D by 8 bits to the right, as you know. This gives 00FF 7B5D. So, if we were just to take that value we would be left with 16743261 as our Green value. Therefore, we bitwise-and that value with the mask of 0xFF (which is equivalent to 0000 00FF) and will result in 00FF 7B5D being 'masked' to 0000 005D. So we have extracted our Green value of 5D (or 93 decimal).

We can use the same mask of 0xFF for each extraction because the values have all been shifted to expose the desired two bytes as the least significant. Hence the previously suggested code of:

int p = pixel[index];

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

If it makes it clearer, you can perform the equivalent operation of:

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

For brevity, the extra 0s can be dropped, and it can be written as

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

Note however, that alternative colour models may be used, such as RGB_555 which stores each pixel as just 2 bytes, with varying precision for the RGB channels. So you should check the model that your bitmap is using before you perform the extraction, because the colours may be stored differently.

多像笑话 2024-11-08 15:18:11

Bitmap#getPixel(x, y)< /code> 返回一个 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);

Bitmap#getPixel(x, y) returns an int with the colour values and alpha value embedded into it.

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);
白云不回头 2024-11-08 15:18:11

这就是我试图获得该价值的方式。使用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;
                 }}

This is how I am trying to get that value. Use bitmap.getPixel() to get the corresponding bitmap in
integer array. By using bitwise rotation operation, we will get RGB values.

             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;
                 }}
深海夜未眠 2024-11-08 15:18:11

任意位图颜色处理

您可以在此处阅读有关各种 Color 方法的信息,这些方法将从像素整数中提取颜色分量。

您可能想要对位图应用过滤器,并返回一个字节数组。否则,您可以将此示例简化为 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;
}

Arbitrary Bitmap Color Handling

You can read about the various Color methods here that will extract the components of color from a pixel int.

You might want to apply a filter to the bitmap, and return a byte array. Otherwise, you can cut this example down to the for-loop and roll through the pixels generating your array of bytes.

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;
}
决绝 2024-11-08 15:18:11

少一个语句: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;
    }

One for statement less :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;
    }
萌吟 2024-11-08 15:18:11

除了@Cobbles的答案之外,您还可以使用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 对象的整数值rel="nofollow noreferrer">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
        ));
    }
}

In addition to @Cobbles' answer, you can also use Bitmap#getColor(x, y) and a Color object.

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

With above code, you can get float (0..1) RGBA values. When you just want to get integer (0..255) values, @Cobble's way is rather straight forward (recommended). Though there is still a way to get integer values with this Color object by using 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
        ));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文