How to fade color

后端 未结 8 1288
我寻月下人不归
我寻月下人不归 2021-02-06 05:56

I would like to fade the color of a pixel out toward white, but obviously maintain the same color. If I have a pixel (200,120,40), will adding 10 to each value to m

相关标签:
8条回答
  • 2021-02-06 06:35

    There are a bunch of ways to do this. How you choose to do it will depend on whether you value speed and simplicity or perceptual uniformity. If you need it to be truly uniform you will need to define you RGB colors with a color profile and you'll need the primaries of the profile so you can convert to XYZ and then to LAB where you can manipulate the L channel.

    Most of the time you don't need to do that and you can instead use a simple HSB model like Photoshop does in the info palette.

    To do this you simply imagine a line between your RGB point and the white point in 3D space and move your color along that line. In practical terms you can just create a parametric equation for that line and move the parameter.

    import numpy as np
    
    def lighter(color, percent):
        '''assumes color is rgb between (0, 0, 0) and (255, 255, 255)'''
        color = np.array(color)
        white = np.array([255, 255, 255])
        vector = white-color
        return color + vector * percent
    

    A percentage of 0.0 will return the same color and 1.0 will return white. Everything between will be a lighter shade of the same hue. This should give you results that agree with Photoshop's HSB implementation, but will be device dependent and may not be perfectly uniform.

    If you have RGB [200, 100, 50] and put in a percentage of .50 it should return RGB[ 227.5 177.5 152.5] Photoshop reports both as a hue of 20º.

    It is not hard to do this without numpy, but the element wise operations are convenient.

    Edit based on comment:

    I'm not suggesting you do this unless you know you really need to do it the hard way. But if you want to convert to LAB you can without too much trouble. The most important thing is that you need to know what color space your RGB numbers are in to begin with or you need to make some assumptions about their meaning. Since sRGB is pretty standard on the web, I'll assume that here.

    The conversions aren't that difficult, but it's easy to make mistakes. Happily, there's a pretty nice colormath module with good documentation: https://github.com/gtaylor/python-colormath

    Using that you can convert between sRGB and LAB like this:

    from colormath.color_objects import sRGBColor, LabColor
    from colormath.color_conversions import convert_color
    
    sRGB = sRGBColor(126, 126, 126, is_upscaled=True) # or between [0, 1] with out is_upscaled
    lab =  convert_color(sRGB, LabColor)
    

    lab now is a color with a Luminance channel lab.lab_l which you can move up or down between black(0) and white(100). This should be more perceptually uniform than HSB (but, depending on your application, maybe not enough to warrant the work).

    You can simply change lab_l and then convert back:

    lab.lab_l = 80
    new_sRGB = convert_color(lab, color_objects.sRGBColor).get_upscaled_value_tuple()
    

    new_sRGB is now [198, 198, 198]. colormath took care of the illuminant and gamma issues for you.

    0 讨论(0)
  • 2021-02-06 06:37

    I prefer to use HSV color mode.

    To grayer your color you have to decrease Saturation factor.

    Standard colorsys module can help in RGB <-> HSV conversions, but please keep in mind: colorsys operates with channel values in range [0, 1), not [0, 256).

    There is full code example:

    >>> from colorsys import hsv_to_rgb, rgb_to_hsv
    >>> color = (200, 120, 40)
    >>> normalized_color = (color[0]/256., color[1]/256., color[2]/256.)
    >>> normalized_color
    (0.78125, 0.46875, 0.15625)
    >>> hsv_color = rgb_to_hsv(*normalized_color)
    >>> hsv_color
    (0.08333333333333333, 0.8, 0.78125)
    >>> grayed_hsv_color = (hsv_color[0], 0.6, hsv_color[2])
    >>> grayed_rgb_color = hsv_to_rgb(*grayed_hsv_color)
    >>> grayed_rgb_color
    (0.78125, 0.546875, 0.3125)
    >>> denormalized_rgb_color = (int(grayed_rgb_color[0]*256), int(grayed_rgb_color[1]*256), int(grayed_rgb_color[2]*256))
    >>> denormalized_rgb_color
    (200, 140, 80)
    
    0 讨论(0)
提交回复
热议问题