0

約4M以上の「JPG」画像を圧縮したいのですが、コードは次のとおりです。

public static void Compress(String sourceFolder,String destFolder,double proportion) throws IOException
{
    File source=new File(sourceFolder);
    File[] sourceFiles=null;
    if(source.isDirectory())
    {
        sourceFiles=source.listFiles();
        for(int i=0;i<sourceFiles.length;i++)
        {
            String name="";
            javax.imageio.ImageIO.setUseCache(false);
            Image src = javax.imageio.ImageIO.read(sourceFiles[i]);
            name=sourceFiles[i].getName();
            int width=src.getWidth(null);
            int height=src.getHeight(null);
            destWidth=(int) (height*proportion);
            destHeight=(int) (width*proportion);
            BufferedImage tag=new BufferedImage(destWidth,destHeight,BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();  
            g.drawImage(src, 0, 0, destWidth, destHeight, null);
            src.flush();
            src=null;
            FileOutputStream out = new FileOutputStream(destFolder+"/"+name);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
            encoder.encode(tag);  
            out.close(); 
        }
    }
    else
        System.exit(0);
}

実行時

Image src = javax.imageio.ImageIO.read("filename");

例外が発生しました:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferByte.<init>(DataBufferByte.java:58)
at java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:397)
at java.awt.image.Raster.createWritableRaster(Raster.java:938)
at javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1056)
at javax.imageio.ImageReader.getDestination(ImageReader.java:2879)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:943)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:915)
at javax.imageio.ImageIO.read(ImageIO.java:1422)
at javax.imageio.ImageIO.read(ImageIO.java:1282)
at functions.CompressImage.Compress(CompressImage.java:50)
at functions.CompressImage.main(CompressImage.java:24)

run引数(-Xms = 1g)を試しましたが、まだ機能しません!誰が解決策を知っていますか?助けてください、ありがとう!

4

2 に答える 2

0

4MB の JPG は、巨大なビットマップ ファイルになります。私は、それだけで多くのメモリが必要になると思います。javax.imagio で大量のメモリ消費についてよく読みます。

ビットマップ サイズを取得するには、image_X * image_Y * (8 ~ 10 ビット * 3(色)) を計算します。

一部の数学を更新します。

カラーチャンネルごとに8ビットを想定しています:

7000 * 4900 * 8 * 3 = 1029000000 ビット = 122MB

メモリ内に 122MB の byte[] が必要です。オペレーティング システム (JVM ではない) がそのメモリ ブロックを作成できない場合、その例外が発生します。

于 2012-07-27T14:00:20.580 に答える
0

ヒープダンプを取得して分析する必要があります。最も簡単な方法は、次のようなJVMパラメーターを追加することです

 -XX:+HeapDumpOnOutOfMemoryError 

これにより、ヒープ ダンプが自動的に作成されます。後で Java プロファイラー (yourkit、jprofiler など) を使用して問題を分析できます。

于 2012-07-26T16:27:03.737 に答える