前段时间我有一些类似的需求(巨大的图像 - 而且,我的情况是16位深度 - 将它们完全放在内存中不是一种选择)。我结束了对PNG库的编码,以顺序方式进行读/写。如果有人发现它有用,它就在这里。
更新:下面是一个示例代码:
public class SampleTileImage {
public static void doTiling(String tiles[], String dest, int nTilesX) {
int ntiles = tiles.length;
int nTilesY = (ntiles + nTilesX - 1) / nTilesX;
ImageInfo imi1, imi2;
PngReader pngr = new PngReader(new File(tiles[0]));
imi1 = pngr.imgInfo;
PngReader[] readers = new PngReader[nTilesX];
imi2 = new ImageInfo(imi1.cols * nTilesX, imi1.rows * nTilesY, imi1.bitDepth, imi1.alpha, imi1.greyscale,
imi1.indexed);
PngWriter pngw = new PngWriter(new File(dest), imi2, true);
pngw.copyChunksFrom(pngr.getChunksList(), ChunkCopyBehaviour.COPY_PALETTE
| ChunkCopyBehaviour.COPY_TRANSPARENCY);
pngr.readSkippingAllRows();
pngr.end();
ImageLineInt line2 = new ImageLineInt(imi2);
int row2 = 0;
for (int ty = 0; ty < nTilesY; ty++) {
int nTilesXcur = ty < nTilesY - 1 ? nTilesX : ntiles - (nTilesY - 1) * nTilesX;
Arrays.fill(line2.getScanline(), 0);
for (int tx = 0; tx < nTilesXcur; tx++) {
readers[tx] = new PngReader(new File(tiles[tx + ty * nTilesX]));
readers[tx].setChunkLoadBehaviour(ChunkLoadBehaviour.LOAD_CHUNK_NEVER);
if (!readers[tx].imgInfo.equals(imi1))
throw new RuntimeException("different tile ? " + readers[tx].imgInfo);
}
for (int row1 = 0; row1 < imi1.rows; row1++, row2++) {
for (int tx = 0; tx < nTilesXcur; tx++) {
ImageLineInt line1 = (ImageLineInt) readers[tx].readRow(row1);
System.arraycopy(line1.getScanline(), 0, line2.getScanline(), line1.getScanline().length * tx,
line1.getScanline().length);
}
pngw.writeRow(line2, row2);
}
for (int tx = 0; tx < nTilesXcur; tx++)
readers[tx].end();
}
pngw.end();
}
public static void main(String[] args) {
doTiling(new String[] { "t1.png", "t2.png", "t3.png", "t4.png", "t5.png", "t6.png" }, "tiled.png", 2);
System.out.println("done");
}
}