我正在做一个功能,像素黑白图像。函数必须被称为pixelate(img, (pixel_width, pixel_height), mode)。
参数(pixel_width, pixel_height)是一个元组,它指示结果像素值的大小。函数必须在任何情况下返回结果,即使它们高于图像维数。如果图像大小不是像素大小的倍数,则一些结果像素的大小将小于(pixel_width, pixel_height)。这个较小的像素将位于图像的右侧和底部边缘,如下面的示例所示。换句话说,像素总是从图像的左上角开始。
参数模式是字符串、'min‘、'max’或‘平均值’。如果我们想要计算新图像像素所在区域的平均值,我们将写“平均值”。我们会写'max‘,如果我们想要最亮的值或最黑暗的'min’。如果平均值有小数,我们将只使用整数部分。
现在我已经完成了程序,但我想写尽可能短的代码,使用尽可能少的CPU内存和时间。
from PIL import Image
import numpy as np
def pixelate_mode(mode):
if mode == 'mean':
return np.mean
elif mode == 'min':
return min
elif mode == 'max':
return max
def pixelate(img, (pixel_width, pixel_height), mode):
width, height = img.size
W = 0
while W * pixel_width < width:
H = 0
while H * pixel_height < height:
l = []
for x in xrange(pixel_width * W, pixel_width * (W + 1)):
for y in xrange(pixel_height * H, pixel_height * (H + 1)):
if x < width and y < height:
l.append(img.getpixel((x, y)))
color = pixelate_mode(mode)(l)
for x in xrange(pixel_width * W, pixel_width * (W + 1)):
for y in xrange(pixel_height * H, pixel_height * (H + 1)):
if x < width and y < height:
img.putpixel((x, y), color)
H += 1
W += 1
return img下面是一些将程序应用于这个映像的例子:它有200×200像素,每平方图像10×10像素。
pixelate(img, (10, 10), 'mean')、pixelate(img, (5, 5), 'max')、pixelate(img, (2, 2), 'min')和pixelate(img, (1, 1), 'mean')返回相同的图像。
pixelate(img, (11, 11), 'mean')返回这。
发布于 2016-01-17 18:04:34
与在嵌套循环中执行color = pixelate_mode(mode)(l)不同,您可以在函数开始时计算一次modefunc = pixelate_mode(mode),然后根据需要调用modefunc(l)。
与检查x和y是否在范围内不同,您只需生成它们,使它们始终在范围内:
l = []
for x in xrange(pixel_width * W, min(width, pixel_width * (W + 1))):
for y in xrange(pixel_height * H, min(height, pixel_height * (H + 1))):
l.append(img.getpixel((x, y)))
color = modefunc(l)
for x in xrange(pixel_width * W, min(width, pixel_width * (W + 1))):
for y in xrange(pixel_height * H, min(height, pixel_height * (H + 1))):
img.putpixel((x, y), color)此外,对于更优化的版本,您只能计算一次限制:
minx, maxx = pixel_width * W, min(width, pixel_width * (W + 1))
miny, maxy = pixel_height * H, min(height, pixel_height * (H + 1))
l = []
for x in xrange(minx, maxx):
for y in xrange(miny, maxy):
l.append(img.getpixel((x, y)))
color = modefunc(l)
for x in xrange(minx, maxx):
for y in xrange(miny, maxy):
img.putpixel((x, y), color)您可以使用列表表达式来定义l。更好的是,您根本不需要l作为列表,只需使用生成器表达式(编辑:显然这对np.array不起作用,所以您必须无论如何构建字符串,可能是使用多个append__s或使用列表理解)。
minx, maxx = pixel_width * W, min(width, pixel_width * (W + 1))
miny, maxy = pixel_height * H, min(height, pixel_height * (H + 1))
color = modefunc(img.getpixel(x, y)
for x in xrange(minx, maxx)
for y in xrange(miny, maxy))
for x in xrange(minx, maxx):
for y in xrange(miny, maxy):
img.putpixel((x, y), color)您可以在嵌套循环之外计算x限制。
您的while循环实际上是伪装的for循环,您可以通过使用for W in range(width/pixel_width)来提高效率,或者可以使用range的step参数来使用您实际需要的值:for w in range(0, width, pixel_width): (在这两种情况下,可能都有一个不一致的问题,但我会让您检查和修复)。
def pixelate(img, (pixel_width, pixel_height), mode):
width, height = img.size
modefunc = pixelate_mode(mode)
for w in range(0, width, pixel_width):
minx, maxx = w, min(width, w + pixel_width)
for h in range(0, height, pixel_height):
miny, maxy = h, min(height, h + pixel_height)
color = modefunc(img.getpixel(x, y)
for x in xrange(minx, maxx)
for y in xrange(miny, maxy))
for x in xrange(minx, maxx):
for y in xrange(miny, maxy):
img.putpixel((x, y), color)
return imghttps://codereview.stackexchange.com/questions/117069
复制相似问题