I have an RGB image and am trying to set every pixel on my RGB to black where the corresponding alpha pixel is black as well. So basically I am trying to "bake" the alpha into my RGB. I have tried this using PIL pixel access objects, PIL ImageMath.eval and numpy arrays:
PIL pixel access objects:
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
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
Numpy array:
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)
The first method works fine, but is really slow. The second method works fine for a single image, but will stop after the first when asked to convert multiple. The third method I created based on this example (first answer): Python: PIL replace a single RGBA color But it fails at the marked command:
data[..., :-1][blackAlphaAreas] = (0, 255, 0, 0)
IndexError: index (295) out of range (0<=index<294) in dimension 0
Numpy seems promising for this kind of stuff, but I dont really get the syntax on how to set parts of the array in one step. Any help? Maybe other ideas to achieve what I describe above quickly?
Cheers