在Python中更改像素颜色:如何更快?

在Python中更改像素颜色:如何更快?,python,image,python-imaging-library,pixel,Python,Image,Python Imaging Library,Pixel,我有一个RGB图像,并试图将RGB上的每个像素设置为黑色,其中相应的alpha像素也是黑色的。所以我基本上是想把阿尔法“烘焙”到我的RGB中。 我使用PIL pixel access对象、PIL ImageMath.eval和numpy数组尝试了这一点: PIL像素访问对象: def alphaCutoutPerPixel(im): pixels = im.load() for x in range(im.size[0]): for y in range(im.s

我有一个RGB图像,并试图将RGB上的每个像素设置为黑色,其中相应的alpha像素也是黑色的。所以我基本上是想把阿尔法“烘焙”到我的RGB中。 我使用PIL pixel access对象、PIL ImageMath.eval和numpy数组尝试了这一点:

PIL像素访问对象:

def alphaCutoutPerPixel(im): pixels = im.load() for x in range(im.size[0]): for y in range(im.size[1]): px = pixels[x, y] r,g,b,a = px if px[3] == 0: # If alpha is black... pixels[x,y] = (0,0,0,0) return im def alphaCutoutPerPixel(im): 像素=im.load() 对于范围内的x(im.尺寸[0]): 对于范围内的y(im.尺寸[1]): px=像素[x,y] r、 g,b,a=px 如果px[3]==0:#如果alpha是黑色的。。。 像素[x,y]=(0,0,0,0) 返回即时消息 PIL ImageMath.eval:

def alphaCutoutPerBand(im): newBands = [] r, g, b, a = im.split() for band in (r, g, b): out = ImageMath.eval("convert(min(band, alpha), 'L')", band=band, alpha=a) newBands.append(out) newImg = Image.merge("RGB", newBands) return newImg def alphaCutoutPerBand(im): 纽班兹=[] r、 g,b,a=im.split() 对于频带输入(r、g、b): out=ImageMath.eval(“转换(最小值(波段,α),‘L’”,波段=波段,α=a) newBands.append(out) newImg=Image.merge(“RGB”,newBands) 返回newImg Numpy阵列:

def alphaCutoutNumpy(im): data = numpy.array(im) r, g, b, a = data.T blackAlphaAreas = (a == 0) # This fails; why? data[..., :-1][blackAlphaAreas] = (0, 255, 0) return Image.fromarray(data) def alphaCutoutNumpy(im): 数据=numpy.array(im) r、 g,b,a=data.T 黑色字母区域=(a==0) #这是失败的;为什么? 数据[…,:-1][blackAlphaAreas]=(0,255,0) 返回Image.fromarray(数据) 第一种方法工作得很好,但速度非常慢。第二种方法适用于单个图像,但当要求转换多个图像时,将在第一种方法之后停止。我基于此示例创建的第三种方法(第一个答案): 但在标记的命令处失败:

data[..., :-1][blackAlphaAreas] = (0, 255, 0, 0)
IndexError: index (295) out of range (0<=index<294) in dimension 0
数据[…,:-1][blackAlphaAreas]=(0,255,0,0)

索引器错误:索引(295)超出范围(0这不使用高级索引,但更易于阅读,imho:

def alphaCutoutNumpy(im):
    data = numpy.array(im)
    data_T = data.T
    r, g, b, a = data_T
    blackAlphaAreas = (a == 0)
    data_T[0][blackAlphaAreas] = 0
    data_T[1][blackAlphaAreas] = 0
    data_T[2][blackAlphaAreas] = 0
    #data_T[3][blackAlphaAreas] = 255
    return Image.fromarray(data[:,:,:3])

切片语法很简单:
数据[x1:x2,y1:y2,z1:z2,…]
是一个n-D切片,其中数据是n-D矩阵,x,y,z,…是维度(逗号分隔),1是起始索引,2是结束索引(中间有冒号)。没有索引意味着无限限制(也就是说,没有下限意味着从头到尾,没有上限意味着从头到尾)。谢谢你的解释Lee!没问题。负索引也从结尾开始。如果你索引
数据[:-1]
你将访问从第一个到第二个到最后一个元素的视图。如果你索引
数据[:-1]
你将访问翻转数组(第二个冒号后面的-1翻转视图,这也意味着您需要索引如下:
data[max:min:-1]
)。试着在解释器中使用小数组。太棒了,罗伯特,谢谢!工作得很好,比第一个PIL方法快30-40%。我本来希望获得更好的速度增益,但这很好。请注意:我认为我的索引器源于“数据”的顺序不同于“BlackAreaAlpha”,即(行x列)和其他(列x行)。