現在、次のコードを使用して、ピクセル値の配列(元はJava.awt.image.PixelGrabberオブジェクトで作成されたもの)をImageオブジェクトに変換しています。
public Image getImageFromArray(int[] pixels, int width, int height) {
MemoryImageSource mis = new MemoryImageSource(width, height, pixels, 0, width);
Toolkit tk = Toolkit.getDefaultToolkit();
return tk.createImage(mis);
}
ImageIOパッケージのクラスを使用して同じ結果を達成できるので、AWTツールキットを使用する必要はありませんか?
Toolkit.getDefaultToolkit()は100%信頼できるようには見えず、AWTErrorがスローされる場合がありますが、ImageIOクラスは常に使用可能である必要があるため、メソッドの変更に興味があります。
ImageIOを使用せずにイメージを作成できます。ピクセル配列の内容と一致する画像タイプを使用して、BufferedImageを作成するだけです。
public static Image getImageFromArray(int[] pixels, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = (WritableRaster) image.getData();
raster.setPixels(0,0,width,height,pixels);
return image;
}
PixelGrabberを使用する場合は、getImageFromArray
を呼び出す前に、ピクセル配列からRGBA情報を抽出することを忘れないでください。この例は、PixelGrabber javadocの handlepixelmethod にあります。それを行ったら、BufferedImageコンストラクタの画像タイプがBufferedImage.TYPE_INT_ARGB
であることを確認してください。
ArrayIndexOutOfBoundsException
を_TYPE_INT_ARGB
_で作成した場合でも、ラスターを使用してBufferedImage
を取得しました。ただし、BufferedImage
のsetRGB(...)
メソッドを使用するとうまくいきました。
BufferedImage.getData()のJavaDocは、「画像データのcopyであるラスター」と言います。
このコードは私にとってはうまくいきますが、私はそれが効率的であることを疑っています:
// Получаем картинку из массива.
int[] pixels = new int[width*height];
// Рисуем диагональ.
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
if (i == j) {
pixels[j*width + i] = Color.RED.getRGB();
}
else {
pixels[j*width + i] = Color.BLUE.getRGB();
//pixels[j*width + i] = 0x00000000;
}
}
}
BufferedImage pixelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
pixelImage.setRGB(0, 0, width, height, pixels, 0, width);
私はJava.awt.Robotを使用してスクリーンショット(または画面のセグメント)を取得することに成功しましたが、ImageIOを使用するには、メモリイメージソースの代わりにBufferedImageに保存する必要があります。次に、ImageIOの静的メソッドを1つ呼び出し、ファイルを保存できます。次のようなものを試してください:
// Capture whole screen
Rectangle region = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capturedImage = new Robot().createScreenCapture(region);
// Save as PNG
File imageFile = new File("capturedImage.png");
ImageIO.write(capturedImage, "png", imageFile);
これはImageIO on SOでタグ付けされた最も投票数の多い質問の1つであるため、質問が古い場合でも、より良い解決策の余地はまだあると思います。 :-)
GitHubにあるオープンソースのimageioプロジェクトの BufferedImageFactory.Java クラスをご覧ください。
それを使うと、あなたは単に書くことができます:
BufferedImage image = new BufferedImageFactory(image).getBufferedImage();
もう1つの良い点は、このアプローチは、最悪の場合、このスレッドにすでにあるPixelGrabber
ベースの例とほぼ同じパフォーマンス(時間)であることです。一般的なほとんどの場合(通常はJPEG)、速度は約2倍です。いずれにせよ、それはより少ないメモリを使用します。
副次的なボーナスとして、デフォルトのカラーモデルでint ARGBに変換される代わりに、元の画像のカラーモデルとピクセルレイアウトが保持されます。これにより、メモリを節約できます。
(追記:ファクトリは、サブサンプリング、関心領域、および進行状況リスナーもサポートしています。