10
  1. Java/GrailsでファイルからBufferedImageに画像を読み込む最速の方法は何ですか?
  2. Java/GrailsでBufferedImageからファイルにイメージを書き込む最速の方法は何ですか?

私のバリアント(読み取り):

byte [] imageByteArray = new File(basePath+imageSource).readBytes()
InputStream inStream = new ByteArrayInputStream(imageByteArray)
BufferedImage bufferedImage = ImageIO.read(inStream)

私のバリアント(書き込み):

BufferedImage bufferedImage = // some image
def fullPath = // image page + file name
byte [] currentImage

try{

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write( bufferedImage, "jpg", baos );
    baos.flush();
    currentImage = baos.toByteArray();
    baos.close();

    }catch(IOException e){
        System.out.println(e.getMessage());
    }       
   }    


def newFile = new FileOutputStream(fullPath)
newFile.write(currentImage)
newFile.close()
4

3 に答える 3

9

読み取るための解決策は、基本的に、バイトをファイルから1回、ファイルから1回、2回読み取ることですByteArrayInputStream。そんなことしないで

Java 7 を使用して読み取る

BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get(basePath + imageSource)));

Java 7 で書く

ImageIO.write(bufferedImage, "jpg", Files.newOutputStream(Paths.get(fullPath)));

への呼び出しは、 (AFAIK)がバッファリングされていないFiles.newInputStreamを返します。ChannelInputStreamあなたはそれを包みたくなるでしょう

new BufferedInputStream(Files.newInputStream(...));

そのため、使用方法に応じて、ディスクへの IO 呼び出しが少なくなります。

于 2013-08-29T23:15:18.787 に答える
5

私はパーティーに遅れましたが、とにかく...

実際には、次を使用します。

ImageIO.read(new File(basePath + imageSource));

ImageIO.write(bufferedImage, "jpeg", new File(fullPath));

...より高速になる可能性があります(確認するために、プロファイラーを使用して試してください)。

これは、これらのバリアントが裏で / にRandomAccessFile基づくImageInputStream/ImageOutputStream実装を使用しているのに対し、InputStream/OutputStreamベースのバージョンはデフォルトでディスクに裏打ちされたシーク可能なストリーム実装を使用するためです。ディスクバッキングには、ストリームの内容全体を一時ファイルに書き込み、場合によってはそこから読み戻すことが含まれます (これは、イメージ I/O が非線形データ アクセスの恩恵を受けることが多いためです)。

ストリーム ベースのバージョンで余分な I/O を回避したい場合は、より多くのメモリを使用することを犠牲にして、あいまいな名前の を呼び出して、シーク可能な入力ストリームのディスク キャッシュImageIO.setUseCache(false)を無効にすることができます。非常に大きな画像を扱っている場合、これは明らかに良い考えではありません。

于 2013-08-30T13:42:31.153 に答える
0

あなたはほとんど書くのが上手です。中間の ByteArrayOutputStream を使用しないでください。これは、コードの大きなボトルネックです。代わりに、FileOutputStream を BufferedOutputStream にラップして、同じことを行います。

同じことがあなたの読書にも当てはまります。Itermediate ByteArrayInputStream を削除します。

于 2013-08-29T23:14:14.417 に答える