2016-12-21 20 views
0

私は現在、PDFを画像に変換し、これらの画像を縮小し、各スケールを異なるタイルに分割するWebサービスを開発中です。Java BufferedImage:事前にメモリサイズを計算

ユーザーのほとんどのデータでは、画像のサイズは大きくなく、プロセス全体がメモリに収まります。

しかし、ベクトル化された大きなPDFを画像に変換すると、解像度が50k +倍の50k解像度になると、1つのBufferedImageインスタンスがメモリに8GB以上のデータを簡単に表示します。

これはWebサーバーなので、できるだけ多くのリクエストを同時に処理したい(スケーリングとタイルを同時に処理することもできます) - メモリ制御の用語が必要です。

私はおそらく、より大きな画像をステップの間にディスクに格納しなければならないことは知っています。実際には、メモリとディスク(BigBufferedImageを参照)を使用できるBufferedImageの便利なオープンソースバージョンがいくつかありますが、特に小さな画像の場合はパフォーマンスのトレードオフがあります。

時間の90%私は問題なくメモリ内のすべてを行うことができます。だから私はしたい:どのように私は事前にBufferedImageのメモリ内のサイズを計算することができますか?私はJavadocを見て、しばらくしてグーグルで止めました。私は実際に画像ファイルフォーマット、カラーモデル、そして専門家の専門家ではありません。どこから始めるべきかわからない。誰でも私がこれらの計算を行うために理解する必要があるもの、可能な正確さ、考慮すべき他のものに私を指摘できますか?

+0

いい計画のようです。これらの画像のソースは何ですか?あなたは事前に何を知っていますか?ピクセルあたりの幅、高さ、ビット数を知っていれば、計算するのはかなり簡単です... – haraldK

+0

@haraldK画像の幅と高さを実際にメモリにロードせずに取得できます。私は 'width * height * 4'を掛けるだけで非常に簡単なアプローチを試み、ロードされた' BufferedImage'インスタンスの 'byte'配列と比較しました。それは20MBのPNG(+/- 100バイト)のために働いたが、〜50MBのPNGのためにそれを計算しようとしたときに、その数は1GB離れていた。 – SakeSushiBig

+0

JPEGのPNGのような圧縮された画像ファイル形式の場合、一般に、ファイルサイズと復号画像のメモリ消費量との間には関係がありません。 'BufferedImage'は、イメージング操作の方が効率的であるため、メモリ内では常に非圧縮です。あなたの計算は32ビットRGBA PNGの場合にのみ正しいです。 – haraldK

答えて

1

一般画像の画素に必要なメモリは、(擬似コード)のようなものを計算することができる:

8.0 byteのビット数であり、そしてまで ceilラウンド
memoryNeeded = ceil(width * height * bitsPerPixel/8.0) 

最も近い整数。いくつかの形式については

、値が直接利用できない場合、あなたは次のようにbitsPerPixelを計算する必要がある場合があります

bitsPerPixel = sum(bitsPerSample for each samplePerPixel) 

それも含まれているように、これらの、BufferedImageため正確なメモリ要件ではありませんRasterColorModelなどを参照していますが、大きな画像の場合、この定数は無視できます。上記の式を使用して計算された値は、イメージをメモリまたはディスクに割り当てるかどうかを決定するのに十分な値でなければなりません。

関連する問題