7

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 への変換を高速化する方法はありますか?

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

4

3 に答える 3

7

この問題は、ソースがByteArrayInputStream. そのため、ファイル システムが遅い場合は、入力ソースに関係なく読み取りも遅くなります。

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

ImageIO.setCacheDirectory(cacheDirectory)一時ファイルを保存するためのより高速なディスク/ramdisk などがある場合は、を使用してキャッシュ ディレクトリを特定のパスに設定することもできます。

とはいえ、ディスクにキャッシュされた読み取りであっても、報告された読み取り時間は不当に高いようです。問題が解決しない場合は、プロファイラーを使用して時間が費やされている場所を見つけ、可能な最適化を検討することをお勧めします。

PS:ByteArrayImageInputStreamディスク アクセスとメモリ消費の両方を減らすのに役立つかもしれないカスタムもあります。これが本当に問題になる場合です。

于 2013-11-22T09:35:23.910 に答える
2

どこから画像を読んでいますか?バイト[]はどこから来るのですか? hdd から画像を読み取っている場合は、 BufferedInputStreamを使用して読み取ると役立つ場合があります。

これにより、読み込みを高速化できます。ただし、これは、たとえばFileInputStreamから読み取る場合にのみ役立ちます。ByteArrayInputStreamから読み取るときは役に立ちません。

編集:あなたが私たちに与えることができるより多くの情報はありますか? バイト配列はどこから来たのですか?

于 2013-11-21T22:37:11.513 に答える