Last active
December 18, 2015 02:59
-
-
Save zeeZ/5714857 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy | |
from PIL import Image | |
def get_matrix(material): | |
# Following Cliff Spradlin's example at http://jsfiddle.net/cliff/jQ8ga/ | |
# https://forum-en.guildwars2.com/forum/community/api/How-To-Colors-API/first#post2148826 | |
brightness = material.brightness / 128. | |
contrast = material.contrast | |
hue = (material.hue * 3.14159265358979323846) / 180. # convert to radians | |
saturation = material.saturation | |
lightness = material.lightness | |
# 4x4 identity matrix | |
matrix = numpy.identity(4) | |
if brightness != 0 or contrast != 1: | |
# process brightness and contrast | |
t = 128 * (2 * brightness + 1 - contrast) | |
mult = numpy.matrix([ | |
[contrast, 0, 0, t], | |
[0, contrast, 0, t], | |
[0, 0, contrast, t], | |
[0, 0, 0, 1] | |
]) | |
matrix = mult * matrix | |
if hue != 0 or saturation != 1 or lightness != 1: | |
# transform to HSL | |
multRgbToHsl = numpy.array([ | |
[ 0.707107, 0., -0.707107, 0], | |
[-0.408248, 0.816497, -0.408248, 0], | |
[ 0.577350, 0.577350, 0.577350, 0], | |
[ 0, 0, 0, 1] | |
]) | |
matrix = multRgbToHsl * matrix | |
# process adjustments | |
cosHue = numpy.cos(hue) | |
sinHue = numpy.sin(hue) | |
mult = numpy.matrix([ | |
[cosHue * saturation, sinHue * saturation, 0, 0], | |
[-sinHue * saturation, cosHue * saturation, 0, 0], | |
[0, 0, lightness, 0], | |
[0, 0, 0, 1] | |
]) | |
matrix = mult * matrix | |
# transform back to RGB | |
multHslToRgb = numpy.matrix([ | |
[ 0.707107, -0.408248, 0.577350, 0], | |
[ 0, 0.816497, 0.577350, 0], | |
[-0.707107, -0.408248, 0.577350, 0], | |
[ 0, 0, 0, 1] | |
]) | |
matrix = multHslToRgb * matrix | |
# Evil sorcery to force our little matrix into a 16 tuple PIL's convert method gladly eats | |
return matrix[0:3,0:4].flatten('C').tolist()[0] | |
def apply_mask(matrix, infile, maskfile): | |
# Open reddish colored emblem template and convert it to RGB without alpha | |
template = Image.open(infile).convert("RGB") | |
# Cliff's example has the color channels backwards | |
b,g,r = template.split() | |
# Create a new image with the reversed color channels, apply our matrix | |
template = Image.merge("RGB", (r,g,b)).convert("RGB", matrix) | |
# ...aaaand put the color channels in the proper order again | |
b,g,r = template.split() | |
template = Image.merge("RGB", (r,g,b)) | |
# Use one of the b&w images as an alpha mask for the colored bits we want | |
mask = Image.open(maskfile).convert("L") | |
template.putalpha(mask) | |
return template | |
def apply_background_mask(matrix, infile): | |
# Open reddish colored emblem background template, make sure it has alpha | |
background = Image.open(infile).convert("RGBA") | |
# Cliff's example has the color channels backwards, also keep alpha | |
b,g,r,a = background.split() | |
# Create new image with the reversed color channels, apply matrix | |
background = Image.merge("RGB", (r,g,b)).convert("RGB", matrix) | |
# ..and again put it back together backwards and add alpha | |
b,g,r = background.split() | |
background = Image.merge("RGBA", (r,g,b,a)) | |
return background | |
def pseuse_put_it_all_together(): | |
# Some random things we're using: | |
# ID of emblem and background | |
emblem_id, canvas_id | |
# Flippin' flags | |
emblem_flags | |
# Our three get_matrixed matrices | |
foreground_matrix, background_matrix, canvas_matrix | |
# Apply color to first emblem bit | |
foreground_layer = apply_mask(foreground_matrix, "emblems/%d.png" % emblem_id, "emblems/%da.png" % emblem_id) | |
# Apply color to other emblem bit | |
background_layer = apply_mask(background_matrix, "emblems/%d.png" % emblem_id, "emblems/%db.png" % emblem_id) | |
# Smoosh them together | |
background_layer.paste(foreground_layer, (0,0), foreground_layer) | |
# Do the flippy doo | |
if "FlipForegroundHorizontal" in emblem_flags: | |
background_layer = background_layer.transpose(Image.FLIP_LEFT_RIGHT) | |
if "FlipForegroundVertical" in emblem_flags: | |
background_layer = background_layer.transpose(Image.FLIP_TOP_BOTTOM) | |
# Result goes here | |
canvas_layer = background_layer | |
if canvas_id > 1: | |
# Emblems that actually do have a background | |
canvas_layer = apply_background_mask(canvas_matrix, "backgrounds/%d.png" % canvas_id) | |
if "FlipBackgroundHorizontal" in emblem_flags: | |
canvas_layer = canvas_layer.transpose(Image.FLIP_LEFT_RIGHT) | |
if "FlipBackgroundVertical" in emblem_flags: | |
canvas_layer = canvas_layer.transpose(Image.FLIP_TOP_BOTTOM) | |
# Put the other stuff on top | |
canvas_layer.paste(background_layer, (0,0), background_layer) | |
return canvas_layer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment