2

I'm looking for a way to change a color's tone, knowing it's RGB composition, then replace all instances of the old RGB with the obtained RGB. For example, I'd like red to become purple, light red, light purple, etc... It can be done in photoshop by changing a color's hue.

What I've thought so far is the following: convert RGB to HLS, then change the Hue.

Here's the code so far (multiple colors are changed, not just one, defined in the "list" list):

(As you might notice, I'm just a beginner and the code itself is pretty dirty; the cleaner parts are probably taken from other SO users) Thanks a lot!

import colorsys

from tempfile import mkstemp
from shutil import move
from os import remove, close

def replace(file, pattern, subst):
    #Create temp file
    fh, abs_path = mkstemp()
    new_file = open(abs_path,'w')
    old_file = open(file)
    for line in old_file:
        new_file.write(line.replace(pattern, subst))
    #close temp file
    new_file.close()
    close(fh)
    old_file.close()
    #Remove original file
    remove(file)
    #Move new file
    move(abs_path, file)

def decimal(var):
    return '{:g}'.format(float(var))

list=[[60,60,60],[15,104,150],[143,185,215],[231,231,231],[27,161,253],[43,43,43],[56,56,56],[255,255,255],[45,45,45],[5,8,10],[23,124,193],[47,81,105],[125,125,125],[0,0,0],[24,24,24],[0,109,166],[0,170,255],[127,127,127]]

for i in range(0,len(list)):
    r=list[i][0]/255
    g=list[i][1]/255
    b=list[i][2]/255
    h,l,s=colorsys.rgb_to_hls(r,g,b)
    print(decimal(r*255),decimal(g*255),decimal(b*255))
    h=300/360
    str1=str(decimal(r*255)) + "," + str(decimal(g*255)) + "," + str(decimal(b*255))
    r,g,b=colorsys.hls_to_rgb(h, l, s)
    print(decimal(r*255),decimal(g*255),decimal(b*255))
    str2=str(decimal(r*255)) + "," + str(decimal(g*255)) + "," + str(decimal(b*255))
    replace("Themes.xml",str1,str2)

EDIT: The problem was pretty simple: R,G,B and H must be between 0 and 1, I was setting them between 0 and 255 and 0 and 360. Updated code.

dlamblin
  • 43,965
  • 20
  • 101
  • 140
GermainZ
  • 1,893
  • 3
  • 15
  • 20
  • do you use Python 3? Otherwise `/` means an integer division without `from __future__ import division` – jfs Jun 16 '12 at 14:39

1 Answers1

2

Your sequence of colors uses integers, but colorsys uses floating point values between 0.0 and 1.0. Divide all the numbers by 255. before putting them through, then multiply by 255 and truncate after getting them back.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358