Changing colour of an image

我怕爱的太早我们不能终老 提交于 2019-12-06 16:29:24
martineau

Here's a Python 3 version of the code in my other answer. It's almost identical except for the imports which had to be changed in order to use the pillow fork of the PIL (because only it supports Python 3). The other changes I made were changing print statements into function calls and where the map() function is used to create the luts look-up table variable.

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')

Here's before and after images. The test image and tint color are the same as what you said you were using when you encountered the problem. The results look very similar to the Py2 version, to yours, and OK to me...am I missing something?

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')

Like this., you can use numpy.

OR

you can use Pillow. [lnk] (https://pillow.readthedocs.org/)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!