有一张非常大的图片无法加载到内存中一次。因为它可能会导致内存不足异常。我需要把这张照片放大到小尺寸。那么我该怎么做呢?
简单的想法是打开一个输入流,一次处理一个缓冲区大小。但是缩放算法呢?
发布于 2012-09-04 09:48:29
有很多不同的大小调整算法,它们提供了不同的质量水平,但代价是cpu时间。
我相信使用这些工具中的任何一个,你都应该能够相对容易地处理大块文件,但是,你可能应该尝试一下现有的工具,看看它们是否已经可以处理大文件了。
Gd图形库允许您定义它可以使用多少工作内存,所以我相信它显然已经有了处理分块文件的逻辑。
发布于 2012-09-04 14:27:35
如果您可以逐行访问图片(例如,它是一个bitmap),那么您可以做的最简单的事情就是downsample它,例如,每n行只读取第n个像素。
// n is an integer that is the downsampling factor
// width, height are the width and height of the original image, in pixels
// down is a new image that is (height/n * width/n) pixels in size
for (y = 0; y < height; y += n) {
row = ... // read row y from original image into a buffer
for (x = 0; x < width; x += n) {
down[y/n, x/n] = row[x]; // image[row,col] -- shorthand for accessing a pixel
}
}这是一种快捷的方法,可以快速而廉价地调整原始图像的大小,而无需将整个图像加载到内存中。不幸的是,它还在输出图像中引入了锯齿(向下)。处理aliasing需要执行插值--仍然可以使用上面的逐行方法,但会稍微复杂一些。
如果您不能轻松地逐行访问图像,例如它是JPEG,它将数据编码为8x8块,您仍然可以执行类似于我上面描述的方法的操作。您只需读取一行块,而不是一行像素--算法的其余部分也是一样的。此外,如果向下采样8倍,那么使用JPEG真的很容易--您只需使用take the DC coefficient of each block。使用这种方法也可以通过因子为8的倍数进行下采样。
我已经介绍了许多其他细节(如颜色通道、像素步幅等),但这应该足以让您上手。
https://stackoverflow.com/questions/12255786
复制相似问题