Получить цвет каждого пикселя изображения с помощью BufferedImages

Я пытаюсь получить каждый цвет каждого пикселя изображения. Моя идея заключалась в следующем:

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

Я просто хотел бы получить цвет каждого пикселя в массиве, как мне этого добиться?

Ответ 1

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 для всех пикселей

Ответ 2

Проблема (также с ответом, которая была связана с первым ответом) заключается в том, что вы почти никогда не знаете, какой именно тип вашего буферизованного изображения будет после чтения с помощью ImageIO. Он может содержать DataBufferByte или DataBufferInt. Вы можете вывести его в некоторых случаях через BufferedImage#getType(), но в худшем случае он имеет тип TYPE_CUSTOM, а затем вы можете вернуться только к некоторым тестам instanceof.

Однако вы можете преобразовать свое изображение в BufferedImage, который, как гарантируется, имеет DataBufferInt с ARGB-значениями, а именно с чем-то вроде

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), который может выполнять требуемые преобразования "на лету".

BTW: Обратите внимание: получение буфера данных BufferedImage может ухудшить производительность графики, поскольку изображение больше не может "управляться" и храниться внутри VRAM внутри.

Ответ 4

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

Ответ 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;
            }
        }
    }
}

Предположим, что буферизованное изображение представляет собой изображение с 8-битными компонентами цвета RGBA, упакованными в целочисленные пиксели, я ищу "цветовое пространство RGBA" в Википедии и обнаружил следующее:

В схеме порядка байтов под RGBA понимается байт R, за которым следует байт G, за которым следует байт B, а за ним следует байт A. Эта схема обычно используется для описания форматов файлов или сетевых протоколов, которые оба ориентированы на байты.

С помощью простых битовых и битовых сдвигов вы можете получить значение каждого цвета и альфа-значение пикселя.

Очень интересна и другая схема заказа RGBA:

В схеме порядка слов под RGBA понимается полное 32-битное слово, где R более значимо, чем G, что более значимо, чем B, что более важно, чем A. Эта схема может использоваться для описания расположение памяти в конкретной системе. Его значение варьируется в зависимости от порядкового номера системы.

Ответ 6

Я знаю, что на этот вопрос уже дан ответ, но приведенные ответы немного запутаны и могут использовать улучшения. Простая идея состоит в том, чтобы просто проходить через каждый (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 ) );
        }

    }

}