改变图像的颜色
Changing colour of an image
用 RGB 值改变整个图像颜色的最简单方法是什么?我试过 wand
,但是 documentation 对我来说意义不大,我只能在 Pillow
文档中找到更改颜色强度的方法。
我在网上尝试了多种解决方案,但是它们要么没有达到我的要求,要么已经过时并且不起作用。
我想要它让整个图像着色,我可以通过更改 RGB 颜色来控制色调,有点像这样:
http://cdn.makeuseof.com/wp-content/uploads/2012/11/Folder-Colorizer-Color-Manager.jpg?69fac7
我可以自己实现轮子,但是实际改变颜色的部分让我很困惑。希望这将是一个简单的解决方案。 :)
import Image
import numpy as nump
img = Image.open('snapshot.jpg')
# In this case, it's a 3-band (red, green, blue) image
# so we'll unpack the bands into 3 separate 2D arrays.
r, g, b = nump.array(img).T
# Let's make an alpha (transparency) band based on where blue is < 100
a = nump.zeros_like(b)
a[b < 100] = 255
# Random math... This isn't meant to look good...
# Keep in mind that these are unsigned 8-bit integers, and will overflow.
# You may want to convert to floats for some calculations.
r = (b + g) * 5
# Put things back together and save the result...
img = Image.fromarray(nump.dstack([item.T for item in (r,g,b,a)]))
img.save('out.png')
像这样,你可以使用numpy。
或
你可以使用 Pillow。
[lnk] (https://pillow.readthedocs.org/)
这是我的 other answer. It's almost identical except for the imports which had to be changed in order to use the pillow
分支中 PIL
代码的 Python 3 版本(因为它只支持 Python 3)。我所做的其他更改是将 print
语句更改为函数调用,其中 map()
函数用于创建 luts
查找 table 变量。
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 = (tuple(map(lambda lr: int(lr*sr + 0.5), range(256))) +
tuple(map(lambda lg: int(lg*sg + 0.5), range(256))) +
tuple(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 += tuple(range(256)) # for 1:1 mapping of copied alpha values
return Image.merge(*merge_args).point(luts)
if __name__ == '__main__':
import os
import sys
input_image_path = 'Dn3CeZB.png'
print('tinting "{}"'.format(input_image_path))
root, ext = os.path.splitext(input_image_path)
suffix = '_result_py{}'.format(sys.version_info[0])
result_image_path = root+suffix+ext
print('creating "{}"'.format(result_image_path))
result = image_tint(input_image_path, '#383D2D')
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')
这是之前和之后的图片。 test image 和 tint 颜色与您遇到问题时所说的相同。结果看起来与你的 Py2 版本非常相似,对我来说还可以……我是不是漏掉了什么?
用 RGB 值改变整个图像颜色的最简单方法是什么?我试过 wand
,但是 documentation 对我来说意义不大,我只能在 Pillow
文档中找到更改颜色强度的方法。
我在网上尝试了多种解决方案,但是它们要么没有达到我的要求,要么已经过时并且不起作用。
我想要它让整个图像着色,我可以通过更改 RGB 颜色来控制色调,有点像这样:
http://cdn.makeuseof.com/wp-content/uploads/2012/11/Folder-Colorizer-Color-Manager.jpg?69fac7
我可以自己实现轮子,但是实际改变颜色的部分让我很困惑。希望这将是一个简单的解决方案。 :)
import Image
import numpy as nump
img = Image.open('snapshot.jpg')
# In this case, it's a 3-band (red, green, blue) image
# so we'll unpack the bands into 3 separate 2D arrays.
r, g, b = nump.array(img).T
# Let's make an alpha (transparency) band based on where blue is < 100
a = nump.zeros_like(b)
a[b < 100] = 255
# Random math... This isn't meant to look good...
# Keep in mind that these are unsigned 8-bit integers, and will overflow.
# You may want to convert to floats for some calculations.
r = (b + g) * 5
# Put things back together and save the result...
img = Image.fromarray(nump.dstack([item.T for item in (r,g,b,a)]))
img.save('out.png')
像这样,你可以使用numpy。
或
你可以使用 Pillow。 [lnk] (https://pillow.readthedocs.org/)
这是我的 other answer. It's almost identical except for the imports which had to be changed in order to use the pillow
分支中 PIL
代码的 Python 3 版本(因为它只支持 Python 3)。我所做的其他更改是将 print
语句更改为函数调用,其中 map()
函数用于创建 luts
查找 table 变量。
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 = (tuple(map(lambda lr: int(lr*sr + 0.5), range(256))) +
tuple(map(lambda lg: int(lg*sg + 0.5), range(256))) +
tuple(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 += tuple(range(256)) # for 1:1 mapping of copied alpha values
return Image.merge(*merge_args).point(luts)
if __name__ == '__main__':
import os
import sys
input_image_path = 'Dn3CeZB.png'
print('tinting "{}"'.format(input_image_path))
root, ext = os.path.splitext(input_image_path)
suffix = '_result_py{}'.format(sys.version_info[0])
result_image_path = root+suffix+ext
print('creating "{}"'.format(result_image_path))
result = image_tint(input_image_path, '#383D2D')
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')
这是之前和之后的图片。 test image 和 tint 颜色与您遇到问题时所说的相同。结果看起来与你的 Py2 版本非常相似,对我来说还可以……我是不是漏掉了什么?