2012-03-07 9 views
0

イメージを読み取るメソッドを書きました。私は画像ファイルのリストをループし、それらを読む。繰り返しの後、Raster.setRect(ラスタラスタ)メソッドを呼び出すときにArrayIndexOutOfBoundsExceptionが表示されます。イメージのディメンションと境界はきれいです - stacktraceを参照してください。ここでArrayIndexOutOfBoundsException Raster.setRect()を呼び出すとき

public static BufferedImage readImage(File imageFile) { 

    // Find a suitable ImageReader 
    Iterator<ImageReader> readers = ImageIO.getImageReadersBySuffix("jpg"); 
    ImageReader reader = null; 
    while (readers.hasNext()) { 
     reader = (ImageReader) readers.next(); 
     if (reader.canReadRaster()) { 
      break; 
     } 
    } 

    // Stream the image file (the original CMYK image) 
    ImageInputStream input = null; 
    try { 
     input = ImageIO.createImageInputStream(imageFile); 
    } catch (IOException e) { 
     logger.error("Error creating InputStream on File {}", imageFile 
       .getName()); 
     e.printStackTrace(); 
    } 
    reader.setInput(input); 

    // Read the image raster 
    Raster raster = null; 
    try { 
     raster = reader.readRaster(0, null); 
    } catch (IOException e) { 
     logger 
       .error("Error reading Raster of file {}", imageFile 
         .getName()); 
     e.printStackTrace(); 
    } 

    // Create a new RGB image 
    BufferedImage bi = new BufferedImage(raster.getWidth(), raster 
      .getHeight(), BufferedImage.TYPE_INT_RGB); 

    // Fill the new image with the old raster 
    logger.debug("Height {} and width {} of original raster", raster 
      .getHeight(), raster.getWidth()); 
    logger.debug("Height {} and width {} of new raster", bi.getRaster() 
      .getHeight(), bi.getRaster().getWidth()); 
    logger.debug("NumBands original raster {}", bi.getRaster().getBounds()); 
    logger.debug("NumBands new raster {}", bi.getRaster().getBounds()); 
    bi.getRaster().setRect(raster); 

    // Close and flush the reader 
    try { 
     input.close(); 
    } catch (IOException e) { 
     logger.error("Error closing the reader for file {}", imageFile 
       .getName()); 
     e.printStackTrace(); 
    } 

    return bi; 
} 

スタックトレース:ドキュメントが言う

13:53:17.065 [main] DEBUG .. .ImageUtils - Height 371 and width 310 of original raster 
13:53:17.065 [main] DEBUG .. .ImageUtils - Height 371 and width 310 of new raster 
13:53:17.065 [main] DEBUG .. .ImageUtils - NumBands original raster java.awt.Rectangle[x=0,y=0,width=310,height=371] 
13:53:17.065 [main] DEBUG .. .ImageUtils - NumBands new raster java.awt.Rectangle[x=0,y=0,width=310,height=371] 

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 310 
at java.awt.image.SinglePixelPackedSampleModel.setPixels(SinglePixelPackedSampleModel.java:689) 
at java.awt.image.WritableRaster.setPixels(WritableRaster.java:565) 
at java.awt.image.WritableRaster.setRect(WritableRaster.java:467) 
at java.awt.image.WritableRaster.setRect(WritableRaster.java:403) 
at .. .utils.ImageUtils.readImage(ImageUtils.java:228) 
at .. .image.scripts.ImageMatchingScript.main(ImageMatchingScript.java:86) 

すべての画像は、ここで同じ大きさ371x310

私が印刷されたデバッグ情報持っては、ArrayIndexOutOfBoundsExceptionを - 座標が境界にない場合、またはfArrayが小さすぎて座標を保持できない場合入力。

私の場合、ディメンション/境界はきれいに見えますが、おそらくfArrayの問題ですか?

答えて

1

問題は画像の大きさではなく、ラスタ内のバンドの数で想像します。 BufferedImage.TYPE_INT_RGBを作成します。 おそらく、失敗した画像はアルファチャンネルのPNGです。その場合、ラスタには追加のバンドがあります。

ImageIo.read(InputStream)を使用するだけではなく、この複雑な方法で読み込みを行う理由がわかりますか?それはあなたにBufferedImageを与え、あなた自身でそれを変換する必要はありません。

編集: 読み取り、RGBに変換するため、この方法を試してください:

InputStream input = null; 
try { 
input = new FileInputStream(...); // whatever your source is 
    BufferedImage rawImage = ImageIO.read(input); 
    if (rawImage == null) 
     return null; 
    BufferedImage rgbImage = new BufferedImage(rawImage.getWidth(null), rawImage.getHeight(null), BufferedImage.TYPE_INT_RGB); 
    Graphics g = rgbImage.createGraphics(); 
    // if rawImage contains alpha, consider filling the rgbImage with a default BG color here 
    g.drawImage(rawImage, 0, 0, null); 
    g.dispose(); 
    rawImage.flush(); 
    return rgbImage; 
} catch (Exception e) { 
// handle error 
    return null; 
} finally { 
    // close input if open 
    if (input != null) { 
     try { 
      input.close(); 
     } catch (IOException e) {} 
    } 
} 

ただ、一緒にコードを強打タイプミスが含まれていてもよいです。このようにして、ソースイメージのプロパティについて考える必要もなく、ソースファイルの内容に関係なく、RGBイメージを取得できます。

+0

あなたは正しい道にいました:私は両方の画像のバンドをチェックしました。 14:59:49.334 [メイン] DEBUG .. .utils.ImageUtils - NumBandsオリジナルのラスタ1 14:59:49.334 [メイン] DEBUG .. .fraud.utils.ImageUtils - 私はこの方法を使用して3 NumBands新しいラスタ画像はCMYKで動いているので読んでいます。これを修正するコードを編集しようとしています – cesmarch

+0

あなたのコードをありがとうございますが、それでもCMYK JPGでは動作しません。私は自分のプロジェクトでJavaCV/OpenCVを使用しているので、イメージ用のRead-Methodとその変換メソッドをBufferedImagesに使用することに決めました。性能は許容可能です。 – cesmarch

+0

CMYKはImageIOのボックスの外ではサポートされていないようです。誰かがCMYK jpgをCMSにアップロードし、CMSによって拡大縮小されたときにイメージが壊れてしまったときに、PHPで同様の問題が発生したことを覚えています。しかし、誰かがすでにImageIOの問題を解決したようです:http://www.randelshofer.ch/blog/2011/08/reading-cmyk-jpeg-images-with-java-imageio/リンクがまだ問題になっている場合助けるかもしれない。 – Durandal

関連する問題