[PIL]: Question On Changing Colour
Hello NG, First of all, sorry if this is not the right newsgroup. I have a small image that looks like a GUI button (with 3D effects given by different pixels colours). The current image has as "basic" colour the grey. For "basic", I mean that the predominant colour in the image is grey and some other pixels are brighter or darker in order to give the 3D effect on that image. Now my question: is it possible to transform the pixels colours in order to have another basic colour (say blue)? In other words, the predominant colour will become the blue, with other pixels in a brighter or darker blue to give the same 3D effects. Thanks a lot for every suggestion, and sorry if it is a basic question. I just started to learn PIL. Andrea. "Imagination Is The Only Weapon In The War Against Reality."http://xoomer.virgilio.it/infinity77 -- http://mail.python.org/mailman/listinfo/python-list
[PIL]: Question On Changing Colour
Hello Terry, > new_hue # your 'basic color', just the hue part> rgb_base # color from the basic button image> rgb_new # the new color you want to replace rgb_base with> > rgb_new = hsv_to_rgb( (new_hue,) + rgb_to_hsv(rgb_base)[1:]) thanks a lot for your suggestion! However, either I did not understand it correctly or I am doing something stupid in my code. Here is a small example: from colorsys import * # that is the old colour --> GREYrgb_old = (0.7, 0.7, 0.7) # Transform the new colour in HSVhsv_old = rgb_to_hsv(rgb_old[0], rgb_old[1], rgb_old[2]) # this is the new colour --> BLUErgb_new = (0.0, 0.0, 1.0) # Transform the new colour in HSVhsv_new = rgb_to_hsv(rgb_new[0], rgb_new[1], rgb_new[2]) # I take only the Hue part of the new colournew_hue = hsv_new[0] # Get the new colourrgb_new = hsv_to_rgb(new_hue, hsv_old[1], hsv_old[2]) print rgb_oldprint rgb_newprint rgb_old == rgb_new This prints: (0.69996, 0.69996, 0.69996)(0.69996, 0.69996, 0.69996)True So, no matter what colour I choose as a "new" colour, the Hue part of the new colour doesn't change in RGB. In other words, leaving the old value for "Saturation" and "Value" makes the presence of the "Hue" part useless. But why in the world does this happen? If a colour is defined by 3 values, changes in every single value should change the colour too... Ah, thanks God for the existence of RGB ;-) Thanks a lot for every suggestion. Andrea. "Imagination Is The Only Weapon In The War Against Reality."http://xoomer.virgilio.it/infinity77 -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
On Wednesday 12 October 2005 05:28 pm, Andrea Gavana wrote: > Now my question: is it possible to transform the pixels colours in order to have another basic colour (say blue)? In other words, the predominant colour will become the blue, with other pixels in a brighter or darker blue to give the same 3D effects. Have a look at the colorsys module. This will allow you to define colors in HSV space, then convert to RGB for image generation. What you want to do sounds like changing only the Hue (H) of the colors. PIL will provide means for efficiently mapping base colors to target colors (IIRC, you'll probably use the 'point' method of Image objects, but check the manual). Once you have that, you can just decide on hues for each button, then do an individual replacement like this: new_hue # your 'basic color', just the hue part rgb_base # color from the basic button image rgb_new # the new color you want to replace rgb_base with rgb_new = hsv_to_rgb( (new_hue,) + rgb_to_hsv(rgb_base)[1:]) Cheers, Terry -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
If you're always going from grey to tinted, then the easiest way is to treat it as a 'P' image with a special palette. I believe this function will prepare the palette: def make_palette(tr, tg, tb): l = [] for i in range(255): l.extend([tr*i / 255, tg*i / 255, tb*i / 255]) return l Here's an example: import Image A, B, C = map(chr, [64, 128, 192]) i = Image.fromstring( 'P', (4,4), ''.join([ B,B,B,B, B,C,C,A, B,C,C,A, B,A,A,A])) i.putpalette(make_palette(64,64,255)) i.show() Jeff pgp0XmK9KEsfO.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
I have tried your solution, Terry: > new_hue # your 'basic color', just the hue part > rgb_base # color from the basic button image > rgb_new # the new color you want to replace rgb_base with > > rgb_new = hsv_to_rgb( (new_hue,) + rgb_to_hsv(rgb_base)[1:]) thanks a lot for your suggestion! However, either I did not understand it correctly or I am doing something stupid in my code. Here is a small example: from colorsys import * # that is the old colour --> GREY rgb_old = (0.7, 0.7, 0.7) # Transform the new colour in HSV hsv_old = rgb_to_hsv(rgb_old[0], rgb_old[1], rgb_old[2]) # this is the new colour --> BLUE rgb_new = (0.0, 0.0, 1.0) # Transform the new colour in HSV hsv_new = rgb_to_hsv(rgb_new[0], rgb_new[1], rgb_new[2]) # I take only the Hue part of the new colour new_hue = hsv_new[0] # Get the new colour rgb_new = hsv_to_rgb(new_hue, hsv_old[1], hsv_old[2]) print rgb_old print rgb_new print rgb_old == rgb_new This prints: (0.69996, 0.69996, 0.69996) (0.69996, 0.69996, 0.69996) True So, no matter what colour I choose as a "new" colour, the Hue part of the new colour doesn't change in RGB. In other words, leaving the old value for "Saturation" and "Value" makes the presence of the "Hue" part useless. But why in the world does this happen? If a colour is defined by 3 values, changes in every single value should change the colour too... Ah, thanks God for the existence of RGB ;-) Thanks a lot for every suggestion. Andrea. "Imagination Is The Only Weapon In The War Against Reality." http://xoomer.virgilio.it/infinity77 -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
Andrea Gavana wrote: > I have tried your solution, Terry: > > > new_hue # your 'basic color', just the hue part > > rgb_base # color from the basic button image > > rgb_new # the new color you want to replace rgb_base with > > > > rgb_new = hsv_to_rgb( (new_hue,) + rgb_to_hsv(rgb_base)[1:]) > > > thanks a lot for your suggestion! However, either I did not understand it > correctly or I am doing something stupid in my code. Here is a small > example: > > from colorsys import * > > # that is the old colour --> GREY > rgb_old = (0.7, 0.7, 0.7) > > # Transform the new colour in HSV > hsv_old = rgb_to_hsv(rgb_old[0], rgb_old[1], rgb_old[2]) > > # this is the new colour --> BLUE > rgb_new = (0.0, 0.0, 1.0) > > # Transform the new colour in HSV > hsv_new = rgb_to_hsv(rgb_new[0], rgb_new[1], rgb_new[2]) > > # I take only the Hue part of the new colour > new_hue = hsv_new[0] > > # Get the new colour > rgb_new = hsv_to_rgb(new_hue, hsv_old[1], hsv_old[2]) > > print rgb_old > print rgb_new > print rgb_old == rgb_new > > > This prints: > > (0.69996, 0.69996, 0.69996) > (0.69996, 0.69996, 0.69996) > True > > So, no matter what colour I choose as a "new" colour, the Hue part of the > new colour doesn't change in RGB. In other words, leaving the old value for > "Saturation" and "Value" makes the presence of the "Hue" part useless. But > why in the world does this happen? If a colour is defined by 3 values, > changes in every single value should change the colour too... Not with HSV. The hue determines which 'color' it will be - red, blue, indigo, whatever. That Saturation determined how vibrant this 'color' will be. V is brightness (I can't remember what the V actually stands for). Each of these values scales from 0 to 1, or 0% to 100%, however you want to thiink about it. If you try and picture the gradient you'd get by plotting this range as a line, then: The H line would be a spectrum of colours, like a rainbow. Say we pick H to be RGB #FF - Red The S line would be a gradient ranging from grey (absense of color) to red. The V line would be a gradient ranging from black (completely dark) to red. So on the HSV scale, grey is represented by a saturation of 0 - meaning none of H is present in the color; the color in question being determined purely by it's brightness (V). So when you pick your HSV triplet for a grey color, you have to set S to 0. You can set H to anything at all - because S is 0, no tint of H will appear in the color at all. Iain http://www.snakebomb.com -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
Try this: >>> import colorsys as cs >>> grey = (.7, .7, .7) >>> blue = (0., 0., 1.) >>> hsv_grey = cs.rgb_to_hsv(*grey) >>> hsv_blue = cs.rgb_to_hsv(*blue) >>> hsv_grey (0.0, 0.0, 0.69996) >>> hsv_blue (0.3, 1.0, 1.0) The problem is that the saturation of the grey is 0. There is no Hue to anything between black and white. Maybe you want something like: def apply_hue(color, rgb): hue, _saturation, _value = cs.rgb_to_hsv(*color) _hue, saturation, value = cs.rgb_to_hsv(*rgb) return cs.hsv_to_rgb(hue, max(.1, saturation), value) Or: def apply_hs(color, rgb): hue, saturation, value = cs.rgb_to_hsv(*color) _hue, _saturation, value = cs.rgb_to_hsv(*rgb) return cs.hsv_to_rgb(hue, saturation, value) --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: [PIL]: Question On Changing Colour
On Thursday 13 October 2005 02:58 pm, Andrea Gavana wrote: > # that is the old colour --> GREY > rgb_old = (0.7, 0.7, 0.7) > > So, no matter what colour I choose as a "new" colour, the Hue part of the new colour doesn't change in RGB. In other words, leaving the old value for "Saturation" and "Value" makes the presence of the "Hue" part useless. But why in the world does this happen? If a colour is defined by 3 values, changes in every single value should change the colour too... Turns out this is a bad example for the HSV transformation. The saturation of pure grey is 0, and the hue is undefined (which means it probably takes a default value, or is left wherever you set it -- it has no effect). So what happens is that an HSV hue change leaves pure grays untouched. The RGB to HSV coordinate transform is going from a 3D cartesian system to a *cylindrical* coordinate system, where the long axis of the cylinder is "value", the radius is "saturation", and the angle is "hue". your neutral gray is going to be about 0.7 up the "value" axis, but with no saturation, the hue makes no difference in the outcome. The transformation I suggested was rotating the HSV system about the axis, by substituting the hue. So, if you had, for example, a bright red, you'd get a bright blue, instead (because we got the hue from "process blue" / rgb=(0,0,1)). But gray stays gray. > Ah, thanks God for the existence of RGB ;-) Well, it may be that the hue transform just isn't what you're looking for. We could also preserve only the value, forcing saturation to 1 and hue to the specified hue: >>> hsv_new = (hue_tgt, 1.0, hsv_old[2]) >>> rgb_new = hsv_to_rgb(*hsv_new) >>> rgb_new (0.0, 0.0, 0.69996) (You might get a more aesthetically pleasing outcome with a less pure color, by setting the saturation lower). Cheers, Terry -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list