使用BufferedImages获取图像的每个像素的颜色

use*_*644 14 java image pixel colors

我试图获得图像每个像素的每种颜色.我的想法如下:

int[] pixels;
BufferedImage image;

image = ImageIO.read(this.getClass.getResources("image.png");
int[] pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
Run Code Online (Sandbox Code Playgroud)

是对的吗?我甚至无法检查"像素"数组包含什么,因为我得到以下错误:

java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt
Run Code Online (Sandbox Code Playgroud)

我只是希望得到阵列中每个像素的颜色,我该如何实现呢?

Bla*_*dow 25

import java.io.*;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

public class GetPixelColor
{
  public static void main(String args[]) throws IOException{
  File file= new File("your_file.jpg");
  BufferedImage image = ImageIO.read(file);
  // Getting pixel color by position x and y 
  int clr=  image.getRGB(x,y); 
  int  red   = (clr & 0x00ff0000) >> 16;
  int  green = (clr & 0x0000ff00) >> 8;
  int  blue  =  clr & 0x000000ff;
  System.out.println("Red Color value = "+ red);
  System.out.println("Green Color value = "+ green);
  System.out.println("Blue Color value = "+ blue);
  }
}
Run Code Online (Sandbox Code Playgroud)

当然你必须为所有像素添加一个for循环

  • @ user2410644像素/颜色作为压缩的`int`返回,这意味着RGBA值形成`int`的单个字节.基本上BlackShadow使用位移来提取单个像素.您可以使用`Color color = new Color(clr,true)`来执行相同的操作,并使用`Color` API来提取组件,这样,恕我直言更容易和更安全;) (8认同)
  • >> 8:右移8位,假设红色= 00000000 00001111,红色>> 16表示11111111 00000000,(00001111消失) (2认同)

Mar*_*o13 7

问题(也与第一个答案相关的答案)是,您几乎不知道在使用ImageIO读取后,您的缓冲图像的确切类型.它可能包含一个DataBufferByte或一个DataBufferInt.你可以在某些情况下通过它来推断它BufferedImage#getType(),但在最坏的情况下,它有类型TYPE_CUSTOM,然后你只能回到一些instanceof测试.

但是,您可以将图像转换为保证DataBufferInt具有ARGB值的BufferedImage - 即类似于

public static BufferedImage convertToARGB(BufferedImage image)
{
    BufferedImage newImage = new BufferedImage(
        image.getWidth(), image.getHeight(),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = newImage.createGraphics();
    g.drawImage(image, 0, 0, null);
    g.dispose();
    return newImage;
}
Run Code Online (Sandbox Code Playgroud)

否则,您可以拨打电话image.getRGB(x,y),可以动态执行所需的转换.

顺便说一句:请注意,获取BufferedImage的数据缓冲区可能会降低绘制性能,因为图像无法再被"管理"并在内部保留在VRAM中.


Lon*_*yen 5

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedImage bufferedImage = ImageIO.read(new File("norris.jpg"));
        int height = bufferedImage.getHeight(), width = bufferedImage.getWidth();
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int RGBA = bufferedImage.getRGB(x, y);
                int alpha = (RGBA >> 24) & 255;
                int red = (RGBA >> 16) & 255;
                int green = (RGBA >> 8) & 255;
                int blue = RGBA & 255;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设缓冲图像表示具有 8 位 RGBA 颜色分量打包到整数像素中的图像,我在维基百科上搜索“RGBA 颜色空间”并发现以下内容:

在字节顺序方案中,“RGBA”被理解为表示字节R,后跟字节G,后跟字节B,再后跟字节A。该方案通常用于描述文件格式或网络协议,它们都是面向字节的。

通过简单的 Bitwise 和 Bitshift,您可以获得每种颜色的值和像素的 alpha 值。

非常有趣的是RGBA的另一种顺序方案:

在字序方案中,“RGBA”被理解为表示一个完整的32位字,其中R比G更重要,G比B更重要,G比A更重要。该方案可以用来描述特定系统上的内存布局。它的含义根据系统的字节顺序而变化。