Sign in to follow this  
pleska

Gradient Effect Plug-In

Recommended Posts

I simply *LOVE* your plug-in. However, I did find a bug in it.

Whenever you have a concave selection, the results are not what is expected.

Here is a screenshot of what I'm trying to say:

GradientBug.jpg

Notice the area pointed to by the orange arrow.

By the way, all convex selections I've tried work as expected.

Hope this is clear.

EDIT: Well, nevermind. I see you pointed out this limitation in your original post. Reading is tech, I hear. :wink:

Share this post


Link to post
Share on other sites
I simply *LOVE* your plug-in. However, I did find a bug in it.

Whenever you have a concave selection, the results are not what is expected.

Here is a screenshot of what I'm trying to say:

GradientBug.jpg

Notice the area pointed to by the orange arrow.

By the way, all convex selections I've tried work as expected.

Hope this is clear.

EDIT: Well, nevermind. I see you pointed out this limitation in your original post. Reading is tech, I hear. :wink:

that's what I was trying to say.

Share this post


Link to post
Share on other sites
I simply *LOVE* your plug-in. However, I did find a bug in it.

Whenever you have a concave selection, the results are not what is expected.

You might be able to get around this limitation by filling your selection in a solid color and then making a square selection rectangle around it and then using the gradient mask color to only gradient fill the color you put in the selection.

Paul

Share this post


Link to post
Share on other sites

I got around the issue by writing my own plug-in. ;)

Here is the codelab code (warning, its not cleaned up, optimized, or commented):

void Render(Surface dst, Surface src, Rectangle rect)
{
   bool AlphaOnly = false; // false=full color, true=alpha channel only
   int Direction = 7;      // 0=vertical, 1=horizontal, 2-3=diagonal, 4=Radial Corner, 5=Radial Side, 6=square, 7=conical
   int SwapColors = 0;     // 0=normal, 1=swapped

   ColorBgra PrimaryColor,SecondaryColor,currpixel;
   double xD,yD;
   double ceiling,outer;
   int FirstR,FirstG,FirstB,FirstAlpha;
   int MaxR,MaxG,MaxB,MaxAlpha;
   int RAdjustmentDirection = 1,GAdjustmentDirection = 1,BAdjustmentDirection = 1,AlphaAdjustmentDirection = 1;
   double MidR,MidG,MidB,MidAlpha;
   int RowR,RowG,RowB,RowAlpha;
   double MaxDistance = 0,CurrDistance = 0;
   long CenterX = 0,CenterY = 0;
   double angle = 0, XPercent = 0, YPercent = 0;
   PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
   Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

   if (SwapColors == 0) {
       PrimaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
       SecondaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
   } else {
       PrimaryColor = (ColorBgra)EnvironmentParameters.SecondaryColor;
       SecondaryColor = (ColorBgra)EnvironmentParameters.PrimaryColor;
   }

   FirstAlpha = PrimaryColor.A;
   MaxAlpha = Math.Abs(SecondaryColor.A-PrimaryColor.A);

   if (PrimaryColor.A > SecondaryColor.A)
   {
       AlphaAdjustmentDirection = -1;
   }

   FirstR = PrimaryColor.R;
   FirstG = PrimaryColor.G;
   FirstB = PrimaryColor.B;

   MaxR = Math.Abs(SecondaryColor.R-PrimaryColor.R);
   MaxG = Math.Abs(SecondaryColor.G-PrimaryColor.G);
   MaxB = Math.Abs(SecondaryColor.B-PrimaryColor.;

   if (PrimaryColor.R > SecondaryColor.R)
   {
       RAdjustmentDirection = -1;
   }
   if (PrimaryColor.G > SecondaryColor.G)
   {
       GAdjustmentDirection = -1;
   }
   if (PrimaryColor.B > SecondaryColor.
   {
       BAdjustmentDirection = -1;
   }

   MidR = (FirstR+(RAdjustmentDirection*(MaxR/2)));
   MidG = (FirstG+(GAdjustmentDirection*(MaxG/2)));
   MidB = (FirstB+(BAdjustmentDirection*(MaxB/2)));
   MidAlpha = (FirstAlpha+(AlphaAdjustmentDirection*(MaxAlpha/2)));

   ceiling = selection.Bottom - selection.Top;
   outer = selection.Right - selection.Left;
   CenterX = (long)(((selection.Right - selection.Left) / 2)+selection.Left);
   CenterY = (long)(((selection.Bottom - selection.Top) / 2)+selection.Top);

   switch(Direction)
   {
       case 4: //corner
           MaxDistance = (double)Math.Sqrt((CenterX-selection.Left)*(CenterX-selection.Left) + (CenterY-selection.Top)*(CenterY-selection.Top));
           break;
       case 5: //short side
           MaxDistance = (double)Math.Min(CenterX-selection.Left,CenterY-selection.Top);
           break;
       default:
           break;
   }
   //System.Windows.Forms.MessageBox.Show("Max Distance: " + MaxDistance.ToString(),"Debug", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Asterisk);

   currpixel = src[selection.Left, selection.Top]; // Not used, but won't compile without it.

   for(int y = rect.Top; y     {
       for (int x = rect.Left; x         {
           if (selectionRegion.IsVisible(x, y))
           {
               currpixel = src[x, y];
               xD = (int)x;
               yD = (int)y;
               switch(Direction)
               {
           		case 1:
                    if (!AlphaOnly)
                    {
                        currpixel.R = (byte)(FirstR+(RAdjustmentDirection*((xD-selection.Left)/outer*MaxR)));
                        currpixel.G = (byte)(FirstG+(GAdjustmentDirection*((xD-selection.Left)/outer*MaxG)));
                        currpixel.B = (byte)(FirstB+(BAdjustmentDirection*((xD-selection.Left)/outer*MaxB)));
                    }
                    currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*((xD-selection.Left)/outer*MaxAlpha)));
                    break;
                   case 0:
                    if (!AlphaOnly)
                    {
                        currpixel.R = (byte)(FirstR+(RAdjustmentDirection*((yD-selection.Top)/ceiling*MaxR)));
                        currpixel.G = (byte)(FirstG+(GAdjustmentDirection*((yD-selection.Top)/ceiling*MaxG)));
                        currpixel.B = (byte)(FirstB+(BAdjustmentDirection*((yD-selection.Top)/ceiling*MaxB)));
                    }
                    currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*((yD-selection.Top)/ceiling*MaxAlpha)));
                    break;
                case 2:
                    if (!AlphaOnly)
                    {
                           RowR = (byte)(FirstR+(RAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxR/2))));
                           RowG = (byte)(FirstG+(GAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxG/2))));
                           RowB = (byte)(FirstB+(BAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxB/2))));
                           currpixel.R = (byte)(RowR+(RAdjustmentDirection*((xD-selection.Left)/outer*(MaxR/2))));
                           currpixel.G = (byte)(RowG+(GAdjustmentDirection*((xD-selection.Left)/outer*(MaxG/2))));
                           currpixel.B = (byte)(RowB+(BAdjustmentDirection*((xD-selection.Left)/outer*(MaxB/2))));
                    }
                       RowAlpha = (byte)(FirstAlpha+(AlphaAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxAlpha/2))));
                       currpixel.A = (byte)(RowAlpha+(AlphaAdjustmentDirection*((xD-selection.Left)/outer*(MaxAlpha/2))));
                    break;
                case 3:
                    if (!AlphaOnly)
                    {
                        RowR = (byte)(MidR+(RAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxR/2))));
                        RowG = (byte)(MidG+(GAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxG/2))));
                        RowB = (byte)(MidB+(BAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxB/2))));
                        currpixel.R = (byte)(RowR-(RAdjustmentDirection*((xD-selection.Left)/outer*(MaxR/2))));
                        currpixel.G = (byte)(RowG-(GAdjustmentDirection*((xD-selection.Left)/outer*(MaxG/2))));
                        currpixel.B = (byte)(RowB-(BAdjustmentDirection*((xD-selection.Left)/outer*(MaxB/2))));
                    }
                       RowAlpha = (byte)(MidAlpha+(AlphaAdjustmentDirection*((yD-selection.Top)/ceiling*(MaxAlpha/2))));
                       currpixel.A = (byte)(RowAlpha-(AlphaAdjustmentDirection*((xD-selection.Left)/outer*(MaxAlpha/2))));
                    break;
                case 4:
                case 5:
                    CurrDistance = (double)Math.Sqrt( ((CenterX-x)*(CenterX-x)) + ((CenterY-y)*(CenterY-y)) );
                    if (CurrDistance 	                    {
                        if (!AlphaOnly)
                        {
                            currpixel.R = (byte)(FirstR+(RAdjustmentDirection*(CurrDistance/MaxDistance*MaxR)));
                            currpixel.G = (byte)(FirstG+(GAdjustmentDirection*(CurrDistance/MaxDistance*MaxG)));
                            currpixel.B = (byte)(FirstB+(BAdjustmentDirection*(CurrDistance/MaxDistance*MaxB)));
   	                    }
                        currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*(CurrDistance/MaxDistance*MaxAlpha)));
                    } else {
                        if (!AlphaOnly)
                        {
                            currpixel.R = SecondaryColor.R;
                            currpixel.G = SecondaryColor.G;
                            currpixel.B = SecondaryColor.B;
   	                    }
                        currpixel.A = SecondaryColor.A;
                    }
                    break;
                case 6:
                    XPercent = Math.Min(Math.Abs(xD-selection.Left),Math.Abs(xD-selection.Right))/(CenterX-selection.Left);
                    YPercent = Math.Min(Math.Abs(yD-selection.Top),Math.Abs(yD-selection.Bottom))/(CenterY-selection.Top);
                    if (XPercent > YPercent)
                    {
                           if (!AlphaOnly)
                           {
                               currpixel.R = (byte)(FirstR+(RAdjustmentDirection*YPercent*MaxR));
                               currpixel.G = (byte)(FirstG+(GAdjustmentDirection*YPercent*MaxG));
                               currpixel.B = (byte)(FirstB+(BAdjustmentDirection*YPercent*MaxB));
   	                    }
                           currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*YPercent*MaxAlpha));
                       }
                       else
                       {
                           if (!AlphaOnly)
                           {
                               currpixel.R = (byte)(FirstR+(RAdjustmentDirection*XPercent*MaxR));
                               currpixel.G = (byte)(FirstG+(GAdjustmentDirection*XPercent*MaxG));
                               currpixel.B = (byte)(FirstB+(BAdjustmentDirection*XPercent*MaxB));
   	                    }
                           currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*XPercent*MaxAlpha));
                       }
                    break;
                case 7:
                    xD = xD - CenterX;
                    yD = yD - CenterY;
                       angle = Math.Atan2(yD,xD)*(180 / Math.PI);
                    if (angle	                    if (!AlphaOnly)
                    {
                           currpixel.R = (byte)(FirstR+(RAdjustmentDirection*(angle/180*MaxR)));
                           currpixel.G = (byte)(FirstG+(GAdjustmentDirection*(angle/180*MaxG)));
                           currpixel.B = (byte)(FirstB+(BAdjustmentDirection*(angle/180*MaxB)));
  	                    }
                       currpixel.A = (byte)(FirstAlpha+(AlphaAdjustmentDirection*(angle/180*MaxAlpha)));
                    break;
                default:
                    break;
               }
               dst[x,y] = currpixel;
           }
       }
   }
}

Illnab1024 really helped me get started. I have sent the code to him and asked him to put a UI on it.

BTW, I added a different circle, a square, and a conical filter.

You can download the updated Gradiants.dll here:

http://paintdotnet.12.forumer.com/viewtopic.php?t=2294

Enjoy. :D

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.

Sign in to follow this