有一张非常大的图片,一次无法加载到内存中。因为它可能会导致内存不足异常。我需要将这张照片缩放到小尺寸。那我该怎么办呢?
简单的想法是打开一个输入流,一次处理一个缓冲区大小。但是缩放算法呢?
最佳答案
如果您可以逐行访问图片(例如,它是 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 block 对数据进行编码,您仍然可以执行与我上面描述的方法类似的操作。您只需读取一行 block 而不是一行像素——算法的其余部分将以相同的方式工作。此外,如果您将采样率降低 8 倍,那么使用 JPEG 真的很容易——您只需 take the DC coefficient of each block .使用这种方法也可以按 8 的倍数的因子进行下采样。</p>
我已经掩盖了许多其他细节(例如颜色 channel 、像素跨度等),但这应该足以让您入门。
关于algorithm - 放大一张大图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12255786/