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

时间:2014-03-13 21:29:59

标签: java image colors pixel

我正在尝试获取图像每个像素的每种颜色。 我的想法是:

int[] pixels;
BufferedImage image;

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

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

java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt

我只想获得数组中每个像素的颜色,我该如何实现?

6 个答案:

答案 0 :(得分:24)

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

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

答案 1 :(得分:6)

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

但是,您可以将图像转换为保证具有ARGB值DataBufferInt的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;
}

否则,您可以致电image.getRGB(x,y),这可能会动态执行所需的转化。

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

答案 2 :(得分:2)

byte[] pixels

int[] pixels

试试这个:Java - get pixel array from image

答案 3 :(得分:2)

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

public class ImageUtil {

    public static Color[][] loadPixelsFromImage(File file) throws IOException {

        BufferedImage image = ImageIO.read(file);
        Color[][] colors = new Color[image.getWidth()][image.getHeight()];

        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                colors[x][y] = new Color(image.getRGB(x, y));
            }
        }

        return colors;
    }

    public static void main(String[] args) throws IOException {
        Color[][] colors = loadPixelsFromImage(new File("image.png"));
        System.out.println("Color[0][0] = " + colors[0][0]);
    }
}

答案 4 :(得分:0)

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

假定缓冲的图像表示将8位RGBA颜色分量打包为整数像素的图像,我在Wikipedia上搜索“ RGBA颜色空间”,发现以下内容:

  

在字节顺序方案中,“ RGBA”应理解为表示字节R,   紧随其后的是字节G,然后是字节B,然后是字节A。   此方案通常用于描述文件格式或网络   都是面向字节的协议。

使用简单的逐位和位移位,您可以获取每种颜色的值和像素的alpha值。

非常有趣的是RGBA的其他订购方案:

  

在单词顺序方案中,“ RGBA”应理解为代表完整的   32位字,其中R比G更重要,而G更重要   比B重要,比B重要。此方案可以   用于描述特定系统上的内存布局。它的   含义取决于系统的字节序。

答案 5 :(得分:0)

我知道已经回答了这个问题,但是给出的答案有些复杂,可以加以改进。 简单的想法是只遍历图像中的每个(x,y)像素,并获得该像素的颜色。

BufferedImage image = MyImageLoader.getSomeImage();
for ( int x = 0; x < image.getWidth(); x++ ) {
    for( int y = 0; y < image.getHeight(); y++ ) {
        Color pixel = new Color( image.getRGB( x, y ) );
        // Do something with pixel color here :)
    }
}

然后您可以将此方法包装在一个类中,并实现Java的Iterable API。

class IterableImage implements Iterable<Color> {

    private BufferedImage image;

    public IterableImage( BufferedImage image ) {
        this.image = image;
    }

    @Override
    public Iterator<Color> iterator() {
        return new Itr();
    }

    private final class Itr implements Iterator<Color> {

        private int x = 0, y = 0;

        @Override
        public boolean hasNext() {
            return x < image.getWidth && y < image.getHeight();
        }

        @Override
        public Color next() {
            x += 1;
            if ( x >= image.getWidth() ) {
                x = 0;
                y += 1;
            }
            return new Color( image.getRGB( x, y ) );
        }

    }

}

其用法可能类似于以下内容

BufferedImage image = MyImageLoader.getSomeImage();
for ( Color color : new IterableImage( image ) ) {
    // Do something with color here :)
}