2016-06-02 2 views
1

私は、バッファされたイメージを対応するピクセル値配列に変換しようとしていました。BufferedImage.getData()。getPixels()の例外

public static double[] createArrFromIm(BufferedImage im){ 
     int imWidth = im.getWidth(); 
     int imHeight = im.getHeight(); 
     double[] imArr = new double[imWidth* imHeight]; 
     im.getData().getPixels(0, 0, imWidth, imHeight, imArr); 
     return imArr; 
} 

このコードブロックを作成した元の著者も、このブロックに最適なサンプル画像をいくつか与えました。私は私のイメージに対して、このブロックを実行しようとするとただし、ブロックは行にバインドされた例外のうち、配列インデックスをスローします(画像は常に125 * 150です):

 im.getData().getPixels(0, 0, imWidth, imHeight, imArr); 

この事件は、私には非常に難解なようです。どんな助けや提案も非常に感知できるでしょう。ありがとう。

+0

あなたは答えを得るのを助けるかもしれないいくつかのヒント:あなたは例外を支援したいときは、必ずフルスタックを追加質問にトレース!また、例外を再現するために特定のイメージが必要な場合は、サンプルファイルとともに、作成または読み取るコードを含める必要があります。最後に、「このコードブロックを作成した作者」を参照してください。コンテキストのコードを見つけた場所にリンクすることをお勧めします。ハッピーコーディング! :-) – haraldK

答えて

-1

ラスタ使用してそれを実行します。@haraldK、のgetData(で指摘したように

public static double[] createArrFromIm(BufferedImage im){ 
    int imWidth = im.getWidth(); 
    int imHeight = im.getHeight(); 
    double[] imArr = new double[imWidth* imHeight]; 
    for (int y=0, nb=0 ; y < imHeight ; y++) 
     for (int x=0 ; x < imWidth ; x++, nb++) 
      imArr[nb] = im.getRaster().getSampleDouble(x, y, 0) ; 
    return imArr; 
} 

を)も動作しますが、それは、ラスタのコピーを返すので、それが遅くなります。

DataBufferを使用する方が高速ですが、ピクセル値に直接アクセスできるため、BufferedImageエンコーディングを管理する必要があります。

あなたがしたことがなぜ機能しなかったのか、ここに答えがあります。 im.getData().getPixels()は配列を返しますが、パラメータとして渡した配列には入りません。パラメータとして渡す配列は戻り値の型を決定するだけです。あなたが本当にをしない限り、@FiReTiTiが言うように

double[] imArr = im.getData().getPixels(0, 0, imWidth, imHeight, (double[])null) ; 
+0

'im.getData()'はすでに 'Raster'を取得しています(とにかく、そのコピーです)、あなたのメソッドはちょうど高速です。なぜあなたのバージョンは動作し、OPは動作しませんか?それはそうではないが、説明は有用だろう。 – haraldK

+0

はい、getData()はコピーを返しますので、決して使用しません。 「OPの」とは何ですか、私はあなたの質問に答えてうれしいです。 – FiReTiTi

+0

OP =オリジナルのポスター。 [ソース](http://www.urbandictionary.com/define.php?term=op)。質問を書いた男。 – haraldK

2

は、あなたの代わりにgetData()方法getRaster()メソッドを使用する必要があります。あなたがたgetDataを使用したいのであれば、あなたがしなければならない(それが最良の選択肢ではありません)画像データのコピー。

ただし、これは例外の原因ではありません。問題は、あなたのdouble配列が単一のバンドのためだけにスペースを割り当てているということです(FiReTiTiのバージョンは、最後のパラメータ0を明示的に残して、最初のバンドだけを要求するため動作します)。これはシングルバンド(グレースケール)の画像では問題ありませんが、RGB、CMYK、または複数のバンドを持つ他のカラーモデルを使用すると仮定します。

修正は以下のように、バンド数を割り当てられたスペースを乗算することである。

public static double[] createArrFromIm(BufferedImage im) { 
    int imWidth = im.getWidth(); 
    int imHeight = im.getHeight(); 
    int imBands = im.getRaster().getNumBands(); // typically 3 or 4, depending on RGB or ARGB 

    double[] imArr = new double[imWidth * imHeight * imBands]; 
    im.getRaster().getPixels(0, 0, imWidth, imHeight, imArr); 

    return imArr; 
} 
関連する問題