web-dev-qa-db-ja.com

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

配列内のすべてのピクセルの色を受け取りたいのですが、どうすればそれを実現できますか?

14
user2410644
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ループを追加する必要があります

24
Black Shadow

問題(最初の回答からリンクされた回答もあります)は、ImageIOで読み込んだ後、バッファリングされた画像がどのような正確なタイプになるかほとんどわからないことです。 DataBufferByteまたはDataBufferIntを含めることができます。 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)を呼び出して、必要な変換をその場で実行できます。

ところで:画像を内部でVRAMに「管理」および保持できなくなるため、BufferedImageのデータバッファーを取得すると、ペイントのパフォーマンスが低下する可能性があることに注意してください。

7
Marco13
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]);
    }
}
2
Daniel
byte[] pixels

じゃない

int[] pixels

これを試してください: Java-画像からピクセル配列を取得

2
Black Shadow
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の順に解釈されると理解されています。この方式は、ファイル形式またはネットワークプロトコルの記述によく使用されます。どちらもバイト指向です。

単純なBitwiseとBitshiftを使用すると、各色の値とピクセルのアルファ値を取得できます。

非常に興味深いのは、RGBAの他の順序スキームです:

語順スキームでは、「RGBA」は完全な32ビットワードを表すと理解されます。RはGよりも重要であり、BはAよりも重要です。このスキームは、特定のシステムのメモリレイアウト。その意味は、システムのエンディアンによって異なります。

1
Long Nguyen

これはすでに回答済みですが、与えられた回答は少し複雑であり、改善が必要な場合があります。単純なアイデアは、画像内のすべての(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 :)
}
0
Robert E Fry