gpt4 book ai didi

python - 使用 PIL 在保持透明度的同时对图像进行着色?

转载 作者:太空狗 更新时间:2023-10-30 00:36:52 26 4
gpt4 key购买 nike

好的,情况是这样的:

我想使用 Python 图像库来“主题化”这样的图像:

主题颜色:swatch showing tint color “#33B5E5”

输入:http://mupload.nl/img/olpiyj9is.png出:http://mupload.nl/img/fiaoq6gk5.png

我在 ImageMagick 中使用这个命令得到了结果:

convert image.png -colorspace gray image.png
mogrify -fill "#33b5e5" -tint 100 image.png
解释:


图像首先被转换为黑白,然后是主题。

我想使用 Python 图像库获得相同的结果。但似乎我在使用它时遇到了一些问题,因为:

  1. 无法处理透明度
  2. 背景(主图像中的透明度)也有主题......

我正在尝试使用这个脚本:

import Image
import ImageEnhance

def image_overlay(src, color="#FFFFFF", alpha=0.5):
overlay = Image.new(src.mode, src.size, color)
bw_src = ImageEnhance.Color(src).enhance(0.0)
return Image.blend(bw_src, overlay, alpha)

img = Image.open("image.png")
image_overlay(img, "#33b5e5", 0.5)

你可以看到我没有先将它转换为灰度,因为这也不适用于透明度。

我很抱歉在一个问题中发布了这么多问题,但我无能为力:$

希望大家明白。

最佳答案

注意:此答案的 PIL 版本有一个 Python 3/pillow fork here .

更新 4:我猜我的回答的上一次更新毕竟不是最后一次。尽管将其转换为仅使用 PIL 是一项重大改进,但有几件事似乎应该有更好、更不尴尬的方法,如果只是 PIL 有能力。

嗯,在仔细阅读了文档和一些源代码之后,我意识到我想做的事情事实上是可能的。代价是现在它必须手动构建查找表,因此整体代码稍微长一些。然而,结果是它只需要调用相对较慢的 Image.point() 方法一次,而不是调用三个。

from PIL import Image
from PIL.ImageColor import getcolor, getrgb
from PIL.ImageOps import grayscale

def image_tint(src, tint='#ffffff'):
if Image.isStringType(src): # file path?
src = Image.open(src)
if src.mode not in ['RGB', 'RGBA']:
raise TypeError('Unsupported source image mode: {}'.format(src.mode))
src.load()

tr, tg, tb = getrgb(tint)
tl = getcolor(tint, "L") # tint color's overall luminosity
if not tl: tl = 1 # avoid division by zero
tl = float(tl) # compute luminosity preserving tint factors
sr, sg, sb = map(lambda tv: tv/tl, (tr, tg, tb)) # per component adjustments

# create look-up tables to map luminosity to adjusted tint
# (using floating-point math only to compute table)
luts = (map(lambda lr: int(lr*sr + 0.5), range(256)) +
map(lambda lg: int(lg*sg + 0.5), range(256)) +
map(lambda lb: int(lb*sb + 0.5), range(256)))
l = grayscale(src) # 8-bit luminosity version of whole image
if Image.getmodebands(src.mode) < 4:
merge_args = (src.mode, (l, l, l)) # for RGB verion of grayscale
else: # include copy of src image's alpha layer
a = Image.new("L", src.size)
a.putdata(src.getdata(3))
merge_args = (src.mode, (l, l, l, a)) # for RGBA verion of grayscale
luts += range(256) # for 1:1 mapping of copied alpha values

return Image.merge(*merge_args).point(luts)

if __name__ == '__main__':
import os

input_image_path = 'image1.png'
print 'tinting "{}"'.format(input_image_path)

root, ext = os.path.splitext(input_image_path)
result_image_path = root+'_result'+ext

print 'creating "{}"'.format(result_image_path)
result = image_tint(input_image_path, '#33b5e5')
if os.path.exists(result_image_path): # delete any previous result file
os.remove(result_image_path)
result.save(result_image_path) # file name's extension determines format

print 'done'

这是一张屏幕截图,左侧显示输入图像,右侧显示相应的输出。上一行是带有 alpha 层的,下一行是类似但没有的。

sample input and output images showing results of image with and without alpha

关于python - 使用 PIL 在保持透明度的同时对图像进行着色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12251896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com