Skip to content

Instantly share code, notes, and snippets.

@tuokri
Created September 5, 2020 23:31
Show Gist options
  • Save tuokri/3edd859fdffa232f846922b51127b31e to your computer and use it in GitHub Desktop.
Save tuokri/3edd859fdffa232f846922b51127b31e to your computer and use it in GitHub Desktop.
import os
from pathlib import Path
from PIL import Image
from PIL.ImageColor import getcolor
from PIL.ImageColor import getrgb
from PIL.ImageOps import grayscale
def image_tint(src_path, tint="#ffffff"):
src_img = Image.open(src_path)
if src_img.mode not in ["RGB", "RGBA"]:
raise TypeError("Unsupported source image mode: {}".format(src_img.mode))
src_img.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_img) # 8-bit luminosity version of whole image
if Image.getmodebands(src_img.mode) < 4:
merge_args = (src_img.mode, (l, l, l)) # for RGB verion of grayscale
else: # include copy of src image"s alpha layer
a = Image.new("L", src_img.size)
a.putdata(src_img.getdata(3))
merge_args = (src_img.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)
def do_it(input_image_path, alpha):
print("tinting '{}'".format(input_image_path))
root, ext = os.path.splitext(input_image_path)
suffix = "_Zombie"
result_image_path = root + suffix + ext
print("creating '{}'".format(result_image_path))
result = image_tint(input_image_path, "#6ff542")
if os.path.exists(result_image_path): # delete any previous result file
os.remove(result_image_path)
result.putalpha(alpha)
result.save(result_image_path) # file name"s extension determines format
print("done")
if __name__ == "__main__":
_alpha = Image.open(r"J:\RS2Export\CHR_VN_VN_Heads\Texture2D\ALPHA.tga").split()[-1]
_images = Path(r"J:\RS2Export")
_images = _images.rglob("*Head*D.tga")
for i in _images:
do_it(str(i.absolute()), _alpha)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment