2013-11-21 11 views
6

JPEG形式の画像を表すバイト配列を受け取り、画像の寸法を返すシンプルなサーバーサイドコードがあります。バッファ付き画像変換のバイト配列を遅く

public String processImage(byte[] data) { 
    long startTime = System.currentTimeMillis(); 
    ByteArrayInputStream stream = new ByteArrayInputStream(data); 
    BufferedImage bufferedImage; 
    bufferedImage = ImageIO.read(stream); 

    int height = bufferedImage.getHeight(); 
    int width = bufferedImage.getWidth(); 

    long endTime = System.currentTimeMillis(); 

    return "height="+height+" | width="+width+" | elapsed="+(endTime-startTime); 
} 

問題はそれほど遅くないことです。 100KBの画像の場合、6秒かかります。 900KBの画像の場合、30秒かかります。それは期待されていますか?バッファリングされたイメージ変換にバイト配列をより高速にする方法はありますか?

参考までに、高さ/幅をつかむことだけが私が意図するものではありません。私は最終的にbufferedImageを処理したいと思っています。だから高さ/幅を取得することは単なるコード例でした。

答えて

0

は、次のコマンドラインオプションを使用してJavaプログラムを実行してみて、それがすべてで物事をスピードアップしている場合を参照してください。

-Djava.awt.headless=true 
+1

ありがとう、私はこれをまだ試していませんが、分離された環境で同じコードを実行しようとしましたが、200KBで20msしかかかりませんでした。だから問題はそれがコードのように見えません。上記の設定は何を正確に行いますか? – baekacaek

+1

@baekacaek:これは、グラフィックスカードを式の外に出します。 BufferedImageをディスプレイに表示することを決して予定していないなら、グラフィックカードのRAMにロードする時間を無駄にする必要はありません。ローカルでコードスニペットを試してみましたが、上記のコマンドラインオプションはテストイメージの実行時間を約250msから約140msに短縮しました。 YMMV。 – Asaph

2

あなたがイメージを読んでいるどこから?どこからバイト[]が来るのですか?もしあなたがhddから画像を読んでいるのであれば、それはBufferedInputStreamを使って読むのに役立ちます。

これにより、読み込みが高速化されます。しかし、これは例えばFileInputStreamから読んでいる場合にのみ役に立ちます。 ByteArrayInputStreamから読むと、それは役に立ちません。

EDIT:は多分より多くの情報は、あなたが私たちを与える可能性がありますか?バイト配列はどこから得られますか?

+0

バイト配列はHTTPボディからのもので、この関数を呼び出すためにApache Tomcat Serverが処理します。 – baekacaek

5

私はこの問題は、デフォルトではImageIOでは、あなたのソースがByteArrayInputStreamであったとしても、(一時ファイルへの)ディスクキャッシュを使用するという事実に関係するかもしれないと思います。したがって、ファイルシステムが遅い場合は、入力ソースに関係なく読み込みが遅くなります。

あなたはImageIO.setUseCache(false)で(より多くのメモリを使用してのコストで)ディスクキャッシュを無効にすることができます。これはあなたのストリームをキャッシュします(逆方向のシークを許可するため)。

テンポラリファイルを格納するディスク/ラムディスクなどが高速の場合は、ImageIO.setCacheDirectory(cacheDirectory)を使用してキャッシュディレクトリを特定のパスに設定することもできます。あなたが報告された、と述べた

は回を読んでディスクキャッシュされた読み取りでものために、不当に高いと思われます。問題が解決しない場合は、プロファイラを使用して時間がどこで使われているかを調べ、可能な最適化を調べることをお勧めします。

PS:私も両方のディスク・アクセスとメモリ消費量を減らすのに役立つかもしれないカスタムByteArrayImageInputStreamを持っている、これは実際には問題にする必要があります。