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

s71maibg  于 2023-08-01  发布在  Java
关注(0)|答案(6)|浏览(123)

我试图得到图像的每一个像素的每一种颜色。我的想法是:

int[] pixels;
BufferedImage image;

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

字符串
是这样吗?我甚至不能检查“pixels”数组包含什么,因为我得到以下错误:

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


我只是想接收数组中每个像素的颜色,我如何实现?

thigvfpy

thigvfpy1#

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循环。

7gcisfzg

7gcisfzg2#

问题(也是从第一个答案中链接的答案)是,您几乎不知道在使用ImageIO阅读缓冲图像后,缓冲图像的确切类型是什么。它可以包含DataBufferByteDataBufferInt。在某些情况下,您可以通过BufferedImage#getType()推断它,但在最坏的情况下,它的类型为TYPE_CUSTOM,然后您只能退回到一些instanceof测试。
但是,您可以将图像转换为BufferedImage,它保证具有ARGB值的DataBufferInt-即类似于

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的数据缓冲区可能会降低绘制性能,因为图像不再可以“管理”并保存在内部VRAM中。

sh7euo9m

sh7euo9m3#

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颜色分量的图像,该8位RGBA颜色分量被打包成整数像素,我在维基百科上搜索“RGBA颜色空间”并发现以下内容:
在字节顺序方案中,“RGBA”被理解为表示字节R,后面是字节G,后面是字节B,并且后面是字节A。此方案通常用于描述文件格式或网络协议,它们都是面向字节的。
使用简单的Bitwise和Bitshift,您可以获得每个颜色的值和像素的alpha值。
非常有趣的是RGBA的另一阶方案:
在字序方案中,“RGBA”被理解为表示完整的32位字,其中R比G更有效,G比B更有效,B比A更有效。该方案可用于描述特定系统上的存储器布局。它的含义因系统的字节序而异。

bakd9h0s

bakd9h0s4#

byte[] pixels

字符串
没有

int[] pixels


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

s4n0splo

s4n0splo5#

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

字符串

ih99xse1

ih99xse16#

我知道这个问题已经得到了答案,但给出的答案有点复杂,需要改进。简单的想法是循环遍历图像中的每个(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 :)
    }
}

字符串
然后,您可以将这个方法 Package 在一个类中,并实现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 :)
}

相关问题