has*_*man 54 python image python-imaging-library
我正在尝试使用Python Image Library使所有白色像素透明.(我是一个C黑客试图学习python所以要温柔)我已经有转换工作(至少像素值看起来正确)但我无法弄清楚如何将列表转换为缓冲区来重新创建图片.这是代码
img = Image.open('img.png')
imga = img.convert("RGBA")
datas = imga.getdata()
newData = list()
for item in datas:
if item[0] == 255 and item[1] == 255 and item[2] == 255:
newData.append([255, 255, 255, 0])
else:
newData.append(item)
imgb = Image.frombuffer("RGBA", imga.size, newData, "raw", "RGBA", 0, 1)
imgb.save("img2.png", "PNG")
Run Code Online (Sandbox Code Playgroud)
cr3*_*333 77
您需要进行以下更改:
(255, 255, 255, 0)
而不是列表[255, 255, 255, 0]
img.putdata(newData)
这是工作代码:
from PIL import Image
img = Image.open('img.png')
img = img.convert("RGBA")
datas = img.getdata()
newData = []
for item in datas:
if item[0] == 255 and item[1] == 255 and item[2] == 255:
newData.append((255, 255, 255, 0))
else:
newData.append(item)
img.putdata(newData)
img.save("img2.png", "PNG")
Run Code Online (Sandbox Code Playgroud)
kei*_*thb 40
您还可以使用像素访问模式来就地修改图像:
from PIL import Image
img = Image.open('img.png')
img = img.convert("RGBA")
pixdata = img.load()
width, height = image.size
for y in xrange(height):
for x in xrange(width):
if pixdata[x, y] == (255, 255, 255, 255):
pixdata[x, y] = (255, 255, 255, 0)
img.save("img2.png", "PNG")
Run Code Online (Sandbox Code Playgroud)
import Image
import ImageMath
def distance2(a, b):
return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]) + (a[2] - b[2]) * (a[2] - b[2])
def makeColorTransparent(image, color, thresh2=0):
image = image.convert("RGBA")
red, green, blue, alpha = image.split()
image.putalpha(ImageMath.eval("""convert(((((t - d(c, (r, g, b))) >> 31) + 1) ^ 1) * a, 'L')""",
t=thresh2, d=distance2, c=color, r=red, g=green, b=blue, a=alpha))
return image
if __name__ == '__main__':
import sys
makeColorTransparent(Image.open(sys.argv[1]), (255, 255, 255)).save(sys.argv[2]);
Run Code Online (Sandbox Code Playgroud)
由于这是目前在寻找“枕头白色到透明”时的第一个 Google 结果,我想补充一点,使用 numpy 也可以实现相同的结果,并且在我的基准测试中(具有大量白色背景的单个 8MP 图像)大约是快 10 倍(大约 300 毫秒与建议解决方案的 3.28 秒)。代码也有点短:
import numpy as np
def white_to_transparency(img):
x = np.asarray(img.convert('RGBA')).copy()
x[:, :, 3] = (255 * (x[:, :, :3] != 255).any(axis=2)).astype(np.uint8)
return Image.fromarray(x)
Run Code Online (Sandbox Code Playgroud)
它也很容易转换为“几乎白色”(例如,一个通道是 254 而不是 255)“几乎透明”的版本。当然这会使整个图片部分透明,除了纯黑色:
def white_to_transparency_gradient(img):
x = np.asarray(img.convert('RGBA')).copy()
x[:, :, 3] = (255 - x[:, :, :3].mean(axis=2)).astype(np.uint8)
return Image.fromarray(x)
Run Code Online (Sandbox Code Playgroud)
备注:这.copy()
是必需的,因为默认情况下 Pillow 图像被转换为只读数组。
小智 5
一种更Pythonic的方式,因为对于大图像来说循环需要很长时间
from PIL import Image
img = Image.open('img.png')
img = img.convert("RGBA")
imgnp = np.array(img)
white = np.sum(imgnp[:,:,:3], axis=2)
white_mask = np.where(white == 255*3, 1, 0)
alpha = np.where(white_mask, 0, imgnp[:,:,-1])
imgnp[:,:,-1] = alpha
img = Image.fromarray(np.uint8(imgnp))
img.save("img2.png", "PNG")
Run Code Online (Sandbox Code Playgroud)
该函数结合了之前解决方案的所有优点:它允许任何背景并使用 numpy(比经典列表更快)。
import numpy as np
from PIL import Image
def convert_png_transparent(src_file, dst_file, bg_color=(255,255,255)):
image = Image.open(src_file).convert("RGBA")
array = np.array(image, dtype=np.ubyte)
mask = (array[:,:,:3] == bg_color).all(axis=2)
alpha = np.where(mask, 0, 255)
array[:,:,-1] = alpha
Image.fromarray(np.ubyte(array)).save(dst_file, "PNG")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
72196 次 |
最近记录: |