アプリで非常に大きな.png
画像を生成します (たとえば、40000x10000 ピクセル)。過度のメモリ使用を避けるために、ImageIO
行ごとに書き込むという事実を利用したため、一度にメモリに保持する必要があるのは 40000 ピクセルだけです (実際にはもう少し多くの 100 行を保持しますが、まだ完全な画像ではありません)。
その後、次のコードを使用して POI ワークブックに画像を追加します。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "png", baos);
int pictureIdx = workbook.addPicture(baos.toByteArray, Workbook.PICTURE_TYPE_PNG);
CreationHelper helper = workbook.getCreationHelper();
Sheet sh = workbook.createSheet("Picture");
Drawing patriarch = sh.createDrawingPatriarch();
ClientAnchort anchor = helper.createClientAnchor();
anchor.setCol1(0);
anchor.setRow1(0);
Picture picture = patriarch.createPicture(anchor, pictureIdx);
picture.resize(); // here's the trouble :(
ここpicture.resize()
での最大の問題は呼び出しです。「優先」画像サイズを決定するために、画像全体をメモリにロードしようとします。この例の画像は、非圧縮時に最大 1.6GB のメモリを消費します。一部のユーザー マシンで 1.6GB のメモリを割り当てようとすると、OOM 例外が発生します。
への呼び出しを省略した場合picture.resize()
、画像は結果の xls に表示されません。サイズから判断すると、ファイル内にありますが、表には表示されません。
イメージ全体のメモリへのロードをスキップする方法はありますか? Pictureに好みの画像サイズを手動で指定できますか?