有一张非常大的图片无法加载到内存中一次。因为它可能会导致内存不足异常。我需要将这张照片放大到小尺寸。那我该怎么办?
简单的想法是打开输入流,并一次处理缓冲区大小。但缩放算法?
答案 0 :(得分:3)
如果您可以逐行访问图片(例如,它是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的倍数进行下采样。</ p>
我已经掩饰了许多其他细节(例如颜色通道,像素步幅等),但它应该足以让你开始。
答案 1 :(得分:1)
有很多不同的调整大小算法可以提供不同的质量水平,权衡时间是cpu时间。
我相信你应该能够相对容易地处理块中的大量文件,但是,您应该尝试使用现有工具来查看他们是否已经可以只处理大量文件。
Gd图形库允许您定义它可以使用多少工作内存我相信它显然已经具有处理文件块的逻辑。