Pratyush

Kill Color Keeper v 1.2

Recommended Posts

Hi All,

This plugin is an improvement on Jotaf's Grim Color Reaper

 

I use this plugin a lot but wanted some improvements, suddenly I realized that the since I can code a little and I can use the skill :biggrin:(?) .

As, Jotaf has mentioned in his post that it is opensource, so I made one mine on Codelab version 3.3.

The enhancement it has that It lets you now to choose color through UI instead of going through selecting primary color. 

It also has an option for keeping color

i.e. while Grim Color Reaper 'kills' a specific color,   Kill Color Keeper has an option to preserve specific color while killing every other one. :)

 

User Interface:

UI is similar to Grim reaper. It has options for tolerance and cut off value. But as a significant improvement, that it has Color Wheel inside UI so you can pick up color as desired. Default is still Primary Color. There are two option for Keep color and Kill color. There are two sliders which are dedicated to these two functions.

I could have made it work with same slider, but default value for kill Color always turned out to make whole image transparent for Keep Color Option. Also, there was a need of different slider description . So, I made two dedicated sliders for them with their own default value and own description.

In version 1.1, there are two sliders: Function Kill Color has only one slider for it while Keep Color has two sliders dedicated to it.

 

Ke1os7u.png

 

1. Original Image: 

wIT4b1K.png

 

2. Kill color white i.e. background.

8YGbRat.png

 

3. Keep Color Blue i.e. for dresses here.

UKLjHSU.png
(Please ignore mistakes in UI name & values, this screen print was taken before final DLL was built.)

 

Versions 1.1 

In Keep Color Option if the original image pixel were transparent like this :arrow-down:

EKnbrDy.png

 

Then Keep Color Options would turn transparent pixels in white color (i.e there were given some opacity while running effect).

YVnWbCJ.png

So new version checks that if Alpha is less than given threshold values. I used first sliders to ignore less opaque pixels. UI is changed, now both sliders will active for Keep Color and only first slider is active for Kill Color.  

 

 

Versions 1.2  Updated UI to select Color.

94pqGO3.png

 

Source Code:

color keeper .png

Kill Color Keeper.cs

 

 

Spoiler

// Name:Kill Color Keeper
// Submenu: Color
// Author: Pratyush
// Title: Kill Color Keeper v1.2
// Version: 1.2.0
// Desc: Removes or Preserves a color while maintaining the alpha information
// Keywords: Color|Transparency|Alpha|Retention|Background
// URL:
// Help:
#region UICode
DoubleSliderControl Amount1 = 1; // [0,20] Color Tolerance:
ColorWheelControl Amount2 = ColorBgra.FromBgr(0,0,0); // [PrimaryColor] {!Amount3} Select Color
CheckboxControl Amount3 = false; // [0,1] Select Colors for Specific Values
ListBoxControl Amount4 = 0; // {Amount3} What color?|Primary Color|Secondary Color|White|Gray|Black
RadioButtonControl Amount5 = 0; // [1] Functions|Kill Color|Keep Color
IntSliderControl Amount6 = 0; // [0,255] Consider transparent any alpha smaller than:
IntSliderControl Amount7 = 255; // [0,255] {!Amount5} Consider transparent any alpha greater than:
#endregion

//Kill Color Keeper by Pratyush
//Based on Original Grim Color Reaper by Jotaf

void Render(Surface dst, Surface src, Rectangle rect)
{
    //ColorBgra color = Amount2;
    ColorBgra color;
    if(!Amount3)
        color = Amount2;
    else
      //selecting things from dropdown
        switch(Amount4)
        {   
            case 0: // Primary color
            
                color = (ColorBgra)EnvironmentParameters.PrimaryColor;
                break;
            case 1: // Secondary color
                color = (ColorBgra)EnvironmentParameters.SecondaryColor;
                break;
            case 2: // White
                color = ColorBgra.White;
                break;
            case 3: // Gray
                color = ColorBgra.Gray;
                break;
            default: // Black
                color = ColorBgra.Black;
                break;
        }   


    //color as double
    double R = color.R, G = color.G, B = color.B;

    ColorBgra pixel;
    double rdif, gdif, bdif;
    double alpha;

    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        for (int x = rect.Left; x < rect.Right; x++)
        {
            pixel = src[x,y];

            //difference between this pixel's color and the color to erase
            rdif = pixel.R - R;
            gdif = pixel.G - G;
            bdif = pixel.B - B;

            //simple way of figuring out the alpha: the more distant the colors,
            //the larger the alpha.
            alpha = Amount1 * Math.Sqrt(rdif*rdif + gdif*gdif + bdif*bdif);

            if (Amount5 != 1)
            {
                if (alpha <= Amount6)  //alpha cut-off (fully transparent)
                    pixel.A = 0;

                else if (alpha < pixel.A)    //only apply change if it causes a pixel to become more
                {                            //transparent (to blend nicely with existing alphas)
                    pixel.A = (byte) alpha;

                    alpha = alpha / 255;  //normalize alpha to range 0..1

                    //we assume that each pixel is the result of linear interpolation between an
                    //unknown foreground color, and the user selected background color, which
                    //means it obeys the equation: (for each of Red, Green and Blue)
                    //  final = foreground*alpha + background*(1-alpha)
                    //we already figured out the alpha, so we just need to invert the equation
                    //to obtain the original foreground color:
                    //  foreground = (final - background*(1-alpha)) / alpha
                    pixel.R = Int32Util.ClampToByte((int) (((double) pixel.R - R*(1-alpha)) / alpha));
                    pixel.G = Int32Util.ClampToByte((int) (((double) pixel.G - G*(1-alpha)) / alpha));
                    pixel.B = Int32Util.ClampToByte((int) (((double) pixel.B - B*(1-alpha)) / alpha));
                }
            }
            else
            {

              	if (Amount6 >= pixel.A);  //Ignore transparent pixels
                    

                else if (alpha >= Amount7)  //alpha cut-off (fully opaque)
                    pixel.A = 0;

                else if (alpha > pixel.A)    //only apply change if it causes a pixel to become more
                {
                    //transparent (to blend nicely with existing alphas)
                    pixel.A = (byte) alpha;

                    alpha = alpha / 255;  //normalize alpha to range 0..1

                    pixel.R = Int32Util.ClampToByte((int) (((double) pixel.R - R*(1-alpha)) / alpha));
                    pixel.G = Int32Util.ClampToByte((int) (((double) pixel.G - G*(1-alpha)) / alpha));
                    pixel.B = Int32Util.ClampToByte((int) (((double) pixel.B - B*(1-alpha)) / alpha));
                }
            }
            dst[x,y] = pixel;
        }
    }
}

 

I personally call it 'Color keeper' but didn't wanted to leave word 'Kill',  I choose one between these  two candidates: "Keep Color Killer" and "Kill Color Keeper".

I hope you all will find it useful. 

 

 

Download here: :arrow-down:

Download

 

Edited by Pratyush
  • Like 4
  • Upvote 5

Share this post


Link to post
Share on other sites

@BoltBait I think this is first published plugin which is made with codelab v3.3 using feature for disabling UI. Thanks and Congratulations for all that work. :mrblue: :beer:.

Edited by Pratyush

Share this post


Link to post
Share on other sites

RGBA (and BGRA) values don't have decimal points. Therefore, the two alpha sliders should be IntSliderControl, not DoubleSliderControl.

 

15 minutes ago, Pratyush said:

Since, Jotaf has mentioned in his post that it is opensource, so I made mine on Codelab version 3.3.

You should also posted your modified source code. Maybe someone will to make enhancements in the future; just as you did.

  • Like 1

Share this post


Link to post
Share on other sites

I am doing that. I have not still completed the post, edited over five times already.

EDIT: Thanks for the insight on BGRA, I am changing slider values.:biggrin:

Edited by Pratyush

Share this post


Link to post
Share on other sites
47 minutes ago, Pratyush said:

//simple way of figuring out the alpha: the more distant the colors,

//the larger the alpha.

alpha = Amount1 * Math.Sqrt(rdif*rdif + gdif*gdif + bdif*bdif);

 

Can you explain this to me?  How does that equal alpha (the level of opacity)?  Maybe you mean delta (the difference of change)?

 

 

Share this post


Link to post
Share on other sites
On 2/3/2018 at 1:31 PM, toe_head2001 said:

Can you explain this to me?  How does that equal alpha (the level of opacity)?  Maybe you mean delta (the difference of change)?

 

Maybe Jotaf can explain that, I was also wondering what that meant. That comment line is from original code so I let that be there. 

Edited by Pratyush

Share this post


Link to post
Share on other sites

 

6 hours ago, toe_head2001 said:

How does that equal alpha (the level of opacity)?  Maybe you mean delta (the difference of change)?

 

@toe_head2001  I think that this is about plugin function. This plugin does doesn't affect RGB channels but only alpha of pixels. The alpha values are changed according to delta of a color. Since final alpha values are depended on that, he may have named like that way. I am also not sure about exact reason.

 

EDIT: I think the idea of plugin is make transparency proportional to euclidean distance between color. So, final alpha is proportional to (some constant)*(Delta of color). Once final alpha is defined the way, we know that final = foreground*alpha + backgroud*(1 - alpha) where is alpha is between 0 and 1.  after solving back for alpha we obtain: foreground = (final - background*(1-alpha)) / alpha. 

Edited by Pratyush

Share this post


Link to post
Share on other sites

Your code has the repeating lines. May I offer you simplify the code by removing extra lines?

Spoiler

// Name:Kill Color Keeper
// Submenu: Color
// Author: Pratyush
// Title: KillColorKeeper
// Version: 1.0.0
// Desc: Removes or Preserves a color while maintaining the alpha information
// Keywords: Color|Transparency|Alpha|Retention
// URL:
// Help:
#region UICode
DoubleSliderControl Amount1 = 1; // [0,20] Color tolerance:
ColorWheelControl Amount2 = ColorBgra.FromBgr(0,0,0); //[PrimaryColor] Select Color
RadioButtonControl Amount3 = 1; // [1] Functions|Keep Color|Kill Color
IntSliderControl Amount4 = 0; // [0,255] {!Amount3} Consider transparent any alpha smaller than:
IntSliderControl Amount5 = 255; // [0,255] {Amount3} Consider transparent any alpha greater than:
#endregion

//Kill Color Keeper by Pratyush
//Based on Original Grim Color Reaper by Jotaf

void Render(Surface dst, Surface src, Rectangle rect)
{
    ColorBgra color = Amount2;


    //color as double
    double R = color.R, G = color.G, B = color.B;

    ColorBgra pixel;
    double rdif, gdif, bdif;
    double alpha;

    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        for (int x = rect.Left; x < rect.Right; x++)
        {
            pixel = src[x,y];

            //difference between this pixel's color and the color to erase
            rdif = pixel.R - R;
            gdif = pixel.G - G;
            bdif = pixel.B - B;

            //simple way of figuring out the alpha: the more distant the colors,
            //the larger the alpha.
            alpha = Amount1 * Math.Sqrt(rdif*rdif + gdif*gdif + bdif*bdif);

            switch (Amount3)
            {
                case 0:
                if (alpha <= Amount4)  //alpha cut-off (fully transparent)
                    pixel.A = 0;
                else if (alpha < pixel.A)    //only apply change if it causes a pixel to become more
                                             //transparent (to blend nicely with existing alphas)
                    pixel.A = (byte) alpha;
                    break;
                case 1:
                if (alpha >= Amount5)  //alpha cut-off (fully opaque)
                    pixel.A = 0;
                else if (alpha > pixel.A)    //only apply change if it causes a pixel to become more
                                             //transparent (to blend nicely with existing alphas)
                    pixel.A = (byte) alpha;
                    break;
            }
            
            alpha = alpha / 255;  //normalize alpha to range 0..1

            //we assume that each pixel is the result of linear interpolation between an
            //unknown foreground color, and the user selected background color, which
            //means it obeys the equation: (for each of Red, Green and Blue)
            //  final = foreground*alpha + background*(1-alpha)
            //we already figured out the alpha, so we just need to invert the equation
            //to obtain the original foreground color:
            //  foreground = (final - background*(1-alpha)) / alpha
            pixel.R = Int32Util.ClampToByte((int) (((double) pixel.R - R*(1-alpha)) / alpha));
            pixel.G = Int32Util.ClampToByte((int) (((double) pixel.G - G*(1-alpha)) / alpha));
            pixel.B = Int32Util.ClampToByte((int) (((double) pixel.B - B*(1-alpha)) / alpha));
            dst[x,y] = pixel;
        }
    }
}

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Great - you are on a roll @Pratyush :star: I will definitely be using this - many thanks :D

 

Oooooh - it's not downloading for me as of this minute :|  Got it now - many thanks :star:

Edited by Pixey
  • Like 1

Share this post


Link to post
Share on other sites
On 2/5/2018 at 12:58 AM, Pixey said:

Got it now - many thanks :star:

It's great that you have got that, I was going to recommend you compile the effect on Codelab itself as the code was present on desktop.

Thanks @Pixey, and thank you very much @lynxster4 for complements.

Edited by Pratyush
  • Like 1

Share this post


Link to post
Share on other sites

Versions 1.1 

value In Keep Color Option if the original image pixel were transparent like this :arrow-down:

EKnbrDy.png

 

Then Keep Color Options would turn transparent pixels in white color (i.e there were given some opacity while running effect).

YVnWbCJ.png

So new version checks that if Alpha is less than given threshold values. I used first sliders to ignore less opaque pixels. UI is changed, now both sliders will active for Keep Color and only first slider is active for Kill Color.  

  • Upvote 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.