34

Javaで画像を処理するのが難しいので、このスレッドを投稿します。画像をbyte[]配列に変換してから逆の操作を実行できるようにしたいので、各ピクセルのRGBを変更して、新しい画像を作成できます。BufferedImageのsetRGB()とgetRGB()は、巨大な画像には遅すぎる可能性があるため、このソリューションを使用したいと思います(間違っている場合は修正してください)。

ここでいくつかの投稿を読んでbyte[]配列(ここなど)を取得し、各ピクセルが赤、緑、青の値を含む配列の3つまたは4つのセルで表されるようにします(追加のアルファ値がある場合は4セルです)、これは私にとって非常に便利で使いやすいです。この配列を取得するために使用するコードは次のとおりです(作成したPixelArrayクラスに格納されています):

public PixelArray(BufferedImage image)
{
    width = image.getWidth();
    height = image.getHeight();
    DataBuffer toArray = image.getRaster().getDataBuffer();
    array = ((DataBufferByte) toArray).getData();
    hasAlphaChannel = image.getAlphaRaster() != null;
}

私の大きな問題は、画像を変換したい場合(たとえば、青/緑の値を削除して赤の値のみを保持する場合)、このbyte[]配列を新しい画像に変換する効率的な方法が見つからないことです。私はそれらの解決策を試しました:

1)DataBufferオブジェクトを作成し、次にSampleModelを作成して、最後にWritableRasterを作成し、次にBufferedImageを作成します(追加のColorModelおよびHashtableオブジェクトを使用)。必要な情報がすべて揃っていないため、機能しませんでした(BufferedImage()コンストラクターのHashtableが何であるかわかりません)。

2)ByteArrayInputStreamを使用します。ByteArrayInputStreamで期待されるbyte[]配列は私のものとは関係がないため、これは機能しませんでした。ファイルの各バイトを表し、各ピクセルの各コンポーネントではありません(各ピクセルに3〜4バイト)...

誰かが私を助けてもらえますか?

4

5 に答える 5

42

これを試して:

private BufferedImage createImageFromBytes(byte[] imageData) {
    ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
    try {
        return ImageIO.read(bais);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
于 2012-11-20T01:51:11.550 に答える
16

ここに記載されているアプローチを試しましたが、何らかの理由でどちらも機能しませんでした。とを使用するByteArrayInputStreamImageIO.read(...)null がbyte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();返されますが、画像データへの直接参照ではなく、画像データのコピーが返されます (こちらも参照)。

ただし、次の方法でうまくいきました。画像データの次元と型がわかっているとしましょう。byte[] srcbufに変換するデータのバッファもにしBufferedImageます。それで、

  1. たとえば、空白の画像を作成します

    img=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    
  2. データ配列をに変換し、画像を塗りつぶすためにRaster使用します。setData

    img.setData(Raster.createRaster(img.getSampleModel(), new DataBufferByte(srcbuf, srcbuf.length), new Point() ) );
    
于 2015-04-03T08:10:22.360 に答える
8
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
byte[] array = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(pixelArray, 0, array, 0, array.length);

結果の画像の Graphics オブジェクトを使用しようとすると、このメソッドは同期しなくなる傾向があります。画像の上に描画する必要がある場合は、2 番目の画像を作成し (これは持続可能で、毎回作成するのではなく再利用できます) drawImage、最初の画像をその上に作成します。

于 2014-06-24T07:50:50.883 に答える
0

ImageIO.read を直接使用する方法は、場合によっては適切ではありません。私の場合、生の byte[] には、画像の幅と高さ、および形式に関する情報は含まれていません。ImageIO.read を使用するだけでは、プログラムが有効なイメージを構築することはできません。

画像の基本情報を BufferedImage オブジェクトに渡す必要があります。

    BufferedImage outBufImg = new BufferedImage(幅、高さ、bufferedImage.TYPE_3BYTE_BGR);

次に、setRGB または setData を使用して BufferedImage オブジェクトのデータを設定します。(setRGB を使用する場合、最初に byte[] を int[] に変換する必要があるようです。その結果、ソース画像データが大きい場合、パフォーマンスの問題が発生する可能性があります。大きな byte[] 型のソース データには setData の方が適しているかもしれません。 .)

于 2018-06-16T02:57:51.287 に答える