Получить цвет каждого пикселя изображения с помощью 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 внутри.
Ответ 3
byte[] pixels
не
int[] pixels
попробуйте следующее: Java - получить пиксельный массив из изображения
Ответ 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 ) );
}
}
}