How to implement a vibrant color mix in your code?

I am trying to implement a vibrant color blend of color in code (C # think for now). I found two pages that tell how to do this, but I don't understand their notation.

http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html https://en.wikipedia.org/wiki/Blend_modes

Does anyone have any idea how to convert it to code? From my end, I have two Color objects with values ​​r, g, b. Can anyone show the algorithm, but using r, g, b values?

thank

Here's my broken implementation:

using System;
using System.Drawing;

namespace CardMaker
{
    class VividLight : ColorFilter
    {
        public override Color GetFilteredColor(Color p1, Color p2)
        {
            int newR = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.R, p2.R))));
            int newG = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.G, p2.G))));
            int newB = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.B, p2.B))));

            return Color.FromArgb(newR, newG, newB);
        }

        private static double GetColor(int c1, int c2)
        {
            if (c2 > 128)
            {
                return 256 - ((256 - c1) / (512 * (c2 - 128)));
            }
            else
            {
                return c1 / (256 - 512 * c2);
            }
        }
    }
}

      

+3


source to share


1 answer


The formula is in terms of floating point numbers at [0, 1], and you've converted it to [0,255]. You have also adjusted the constants used in the formula accordingly.

However, some of these constants had an additive role, and some of them had a multiplicative role. What you have to do between these cases is different. The numbers to be added can be scaled as you did, but the numbers to be multiplied should not be (the result will already be properly scaled since the other multiplier (one of the color values) will already be scaled). This is in direct analogy with the problems one has to face when implementing multiplication in fixed-point arithmetic.

Here, wherever you said 512, you should say 2.



As a side note, you should be aware of the possible tradeoff between speed and floating point integer precision. Your method says it returns a double, but the expression in the return statement evaluates to int (and uses integer division, rounding down). This result is then expanded by the compiler to a double after being evaluated. It is possible that your results will be more accurate (and slower) using floating point division (use the constant 2.0 instead of 2 for this) - although since no multiplication occurs after your division, this may not matter much. Try both directions.

    private static double GetColor(int c1, int c2)
    {
        if (c2 > 128)
        {
            return 256 - ((256 - c1) / (2 * (c2 - 128)));
        }
        else
        {
            return c1 / (256 - 2 * c2);
        }
    }

      

0


source







All Articles