PixmapIO提供pixmap数据的读与写,具体就是pixmap数据和cim、png数据格式的转换,使用方式参考官方网站。但本人在使用过程中发现PixmapIO在保存到PNG格式的图片时经常会遇到OOM的问题,跟踪源码,部分截取如下:
static byte[] write (Pixmap pixmap) throws IOException {
byte[] signature = new byte[] {(byte)137, (byte)80, (byte)78, (byte)71, (byte)13, (byte)10, (byte)26, (byte)10};
byte[] header = PNG.createHeaderChunk(pixmap.getWidth(), pixmap.getHeight());
byte[] data = PNG.createDataChunk(pixmap);
byte[] trailer = PNG.createTrailerChunk();
ByteArrayOutputStream png = new ByteArrayOutputStream(signature.length + header.length + data.length + trailer.length);
png.write(signature);
png.write(header);
png.write(data);
png.write(trailer);
return png.toByteArray();
}
和
static private byte[] toZLIB (byte[] raw) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(raw.length + 6 + raw.length / ZLIB_BLOCK_SIZE * 5);
DataOutputStream zlib = new DataOutputStream(baos);
byte tmp = (byte)8;
zlib.writeByte(tmp); // CM = 8, CMINFO = 0
zlib.writeByte((31 - (tmp << 8) % 31) % 31); // FCHECK
// (FDICT/FLEVEL=0)
int pos = 0;
while (raw.length - pos > ZLIB_BLOCK_SIZE) {
writeUncompressedDeflateBlock(zlib, false, raw, pos, (char)ZLIB_BLOCK_SIZE);
pos += ZLIB_BLOCK_SIZE;
}
writeUncompressedDeflateBlock(zlib, true, raw, pos, (char)(raw.length - pos));
// zlib check sum of uncompressed data
zlib.writeInt(calcADLER32(raw));
return baos.toByteArray();
发现源码使用了2倍pixmap数据的buffer,如若保存较大的pixmap,单这一功能就需要几M甚至十几M的内存,就有可能造成OOM。