我在我的应用程序中生成了一些相当大.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 中 - 它在文件中,从大小来看,但它在表中不可见。
有没有办法跳过将整个图像加载到内存中?也许我可以手动为图片提供首选图像尺寸?