Skip to content

Instantly share code, notes, and snippets.

@zeeZ
Last active December 18, 2015 02:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeeZ/5714857 to your computer and use it in GitHub Desktop.
Save zeeZ/5714857 to your computer and use it in GitHub Desktop.
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