Jump to content

CodeLab - First Steps (Neon Edges)


ReMake

Recommended Posts

I think at least sometimes you notice the attractive glow of a neon sign. Perhaps you would like to have the effect imitating this glow.

Let's make experiment with the image before to create our new effect .
Load some any image.

 

56122.jpg

 

Apply to the image the Outline effect (Effects -> Stylize -> Outline). Set a Thickness to 8 and Intensity to 60. Now our image looks so:

 

roose-outline-en.jpg

Apply to the image the Invert Colors effect (Adjustments -> Invert Colors). Look at the image.

 

rooseinvcolor.jpg
We have gained the effect simulating a neon glow. Yet do not close resulting image.

Let's create our effect now. Open your source image in the new window.

Start CodeLab (Effects-> Advanced-> CodeLab). Choose in the menu File -> New. In a dialogue box Script Editor click a No button. The dialogue window the New Source (Template) will be presented to you. In the drop-down list choose Outline and in the one of two drop-down list PixelOp choose Invert. Click the Generate Code button.

 

We will receive the following script of effect:

#region UICode
int Amount1 = 3; // [1,200] Thickness
int Amount2 = 50; // [1,100] Intensity
#endregion

// Setup for using pixel op
private UnaryPixelOps.Invert invertOp = new UnaryPixelOps.Invert();

// Here is the main render loop function
void Render(Surface dst, Surface src, Rectangle rect)
{
    // Setup for calling the Outline effect
    OutlineEffect outlineEffect = new OutlineEffect();
    PropertyCollection outlineProps = outlineEffect.CreatePropertyCollection();
    PropertyBasedEffectConfigToken outlineParameters = new PropertyBasedEffectConfigToken(outlineProps);
    outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Thickness, Amount1);
    outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Intensity, Amount2);
    outlineEffect.SetRenderInfo(outlineParameters, new RenderArgs(dst), new RenderArgs(src));
    // Call the Outline function
    outlineEffect.Render(new Rectangle[1] { rect }, 0, 1);

    // Now in the main render loop, the dst canvas has an outlined version of the src canvas
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
      if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
          ColorBgra CurrentPixel = dst[x,y];

    // TODO: Add additional pixel processing code here
    CurrentPixel = invertOp.Apply(CurrentPixel);

    dst[x,y] = CurrentPixel;
    }
  }
}

It was established experimentally that for the Thickness variable most acceptable range from 1 to 25, and for the Intensity variable - from 15 to 65. Let's change these variables. Open the designer interface (File -> User Interface Designer), select in it the Thickness line and write 25 in the Maximum box. Click the Update button. Select an Intensity line.Write 1 in the Minimum box, in the Maximum box - 50, and in the Default box - 25. Rename this variable to Glow Intensity. Click the Update button, then click button Ok.

Change in the line outlineParameters. SetPropertyValue (OutlineEffect. PropertyNames. Intensity, Amount2); variable Amount2 to Amount2+14 (are you remember that the effective value of Intensity variable begins with 15).

outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Intensity, Amount2+14);

Save our script with the NeonEdges_1 name (File -> Save...) and create a DLL file with the same name (File-> Save as DLL...). Check how your effect works with next parameters: Thickness = 8, Glow Intensity = 45. Compare result with the previous image. They are absolutely identical.

We have achieved the desired result. But, you might want to change the color of the resulting edges.

Go back to the first image. Apply to him the Hue / Saturation effect (Adjustments -> Hue / Saturation) with the different parameters of hue, and saturation. Note that most effectively saturation varies in the range from 100 to 200. Remember that.

And again, let's address to the wonderful CodeLab Help (part 3) tutorial by BoltBait. In the Unary Pixel Operations section we have find the processing operations of hue, and saturation.

Copy a line from this text:

private UnaryPixelOps.HueSaturationLightness saturationOp;

and paste it into our script after the line

private UnaryPixelOps.Invert invertOp = new UnaryPixelOps.Invert();

Now copy from the tutorial the following lines:

// create a saturation operation based on a UI slider
saturationOp = new UnaryPixelOps.HueSaturationLightness(0, Amount1, 0); // fix
CurrentPixel = saturationOp(CurrentPixel);

and paste it after the CurrentPixel = invertOp.Apply(CurrentPixel); line.

Do not forget to correct line CurrentPixel = saturationOp(CurrentPixel); to CurrentPixel = saturationOp.Apply(CurrentPixel);

 

Open the designer interface (File -> User Interface Designer), In the drop-down list Control Type, select the Integer Slider. In the Control name box write the Hue. Write -180 in the Minimum box, in the Maximum box - 100, and in the Default box - 0. Click the Add button. Select the Integer Slider in the drop-down list Control type again. In the Control name box write the Saturation. Write 25 in the Default box. Click the Update button, then click button Ok.

Now the code block looks as follows:

#region UICode
int Amount1 = 8; // [1,25] Thickness
int Amount2 = 45; // [1,50] Glow Intensity
int Amount3 = 0; // [-180,180] Hue
int Amount4 = 0; // [0,100] Saturation
#endregion

Let's change in the line saturationOp = new UnaryPixelOps.HueSaturationLightness(0, Amount1, 0); values in parentheses. Write Amount3 instead first 0, and write (Amount4+100)*2 instead Amount1.

Now our script looks like this:

#region UICode
int Amount1 = 8; // [1,25] Thickness
int Amount2 = 45; // [1,50] Glow Intensity
int Amount3 = 0; // [-180,180] Hue
int Amount4 = 0; // [0,100] Saturation
#endregion

// Setup for using pixel op
private UnaryPixelOps.Invert invertOp = new UnaryPixelOps.Invert();
private UnaryPixelOps.HueSaturationLightness saturationOp;

// Here is the main render loop function
void Render(Surface dst, Surface src, Rectangle rect)
{
  // Setup for calling the Outline effect
  OutlineEffect outlineEffect = new OutlineEffect();
  PropertyCollection outlineProps = outlineEffect.CreatePropertyCollection();
  PropertyBasedEffectConfigToken outlineParameters = new PropertyBasedEffectConfigToken(outlineProps);
  outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Thickness, Amount1);
  outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Intensity, Amount2 + 14);
  outlineEffect.SetRenderInfo(outlineParameters, new RenderArgs(dst), new RenderArgs(src));
  // Call the Outline function
  outlineEffect.Render(new Rectangle[1] { rect }, 0, 1);

    // Now in the main render loop, the dst canvas has an outlined version of the src canvas
    for (int y = rect.Top; y < rect.Bottom; y++)
    {
      if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
           ColorBgra CurrentPixel = dst[x,y];

           CurrentPixel = invertOp.Apply(CurrentPixel);

    // Create a hue & saturation operation based on a UI slider
    saturationOp = new UnaryPixelOps.HueSaturationLightness(Amount3, (Amount4 + 100)*2, 0); // fix
    CurrentPixel = saturationOp.Apply(CurrentPixel);

    // TODO: Add additional pixel processing code here

    dst[x,y] = CurrentPixel;
    }
  }
}

Save it with the name NeonEdges_2 and create a DLL file with the same name. Check your effect in the work.

Maybe you want to eliminate the dark areas of the image to use this image with a different background. For this requires set to each pixel a maximum value of one of the three components R, G, or B.

We need an R, G, B and A integer variables, as well as one more control.

Open the Designer interface and in the drop-down list Control type, select the Check Box. In the Control name box write Eliminate dark areas. Click Add button and then button Ok.

The code block of user interface will look like this:

#region UICode
int Amount1 = 8; // [1,25] Thickness
int Amount2 = 45; // [1,50] Glow Intensity
int Amount3 = 0; // [-180,180] Hue
int Amount4 = 0; // [0,100] Saturation
bool Amount5 = false; // [0,1] Eliminate dark areas
#endregion

Below the commented line TODO: add the following code:

        // TODO: Add additional pixel processing code here
        int R = CurrentPixel.R;
        int G = CurrentPixel.G;
        int B = CurrentPixel.B;
        int A = CurrentPixel.A;
        if (Amount5)
          {A = Math.Max(Math.Max(R,G),В);}
            CurrentPixel.A = Int32Util.ClampToByte(A);

It remains to add some information:

// Author: ReMake
// Submenu: Stylize
// Name: Neon Edges
// Title: Neon Edges
// Desc: The Paint.Net effect that simulates neon edges of the image
// Keywords: paint.net|effect|neon|edges
// URL: http://www.getpaint.net/redirect/plugins.html

and our final script will look like this:

// Author: ReMake
// Submenu: Stylize
// Name: Neon Edges
// Title: Neon Edges
// Desc: The Paint.Net effect that simulates neon edges of the image
// Keywords: paint.net|effect|neon|edges
// URL: http://www.getpaint.net/redirect/plugins.html
#region UICode
int Amount1 = 8; // [1,25] Thickness
int Amount2 = 45; // [1,50] Glow Intensity
int Amount3 = 0; // [-180,180] Hue
int Amount4 = 25; // [0,100] Saturation
bool Amount5 = false; // [0,1] Eliminate dark areas
#endregion

// Setup for using pixel op
private UnaryPixelOps.Invert invertOp = new UnaryPixelOps.Invert();
private UnaryPixelOps.HueSaturationLightness saturationOp;

// Here is the main render loop function
void Render(Surface dst, Surface src, Rectangle rect)
{
// Setup for calling the Outline effect
OutlineEffect outlineEffect = new OutlineEffect();
PropertyCollection outlineProps = outlineEffect.CreatePropertyCollection();
PropertyBasedEffectConfigToken outlineParameters = new PropertyBasedEffectConfigToken(outlineProps);
outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Thickness, Amount1);
outlineParameters.SetPropertyValue(OutlineEffect.PropertyNames.Intensity, Amount2 + 14);
outlineEffect.SetRenderInfo(outlineParameters, new RenderArgs(dst), new RenderArgs(src));
// Call the Outline function
outlineEffect.Render(new Rectangle[1] { rect }, 0, 1);

// Now in the main render loop, the dst canvas has an outlined version of the src canvas
for (int y = rect.Top; y < rect.Bottom; y++)
{
  if (IsCancelRequested) return;
    for (int x = rect.Left; x < rect.Right; x++)
    {
      ColorBgra CurrentPixel = dst[x, y];
      CurrentPixel = invertOp.Apply(CurrentPixel);

    // Create a hue & saturation operation based on a UI slider
    saturationOp = new UnaryPixelOps.HueSaturationLightness(Amount3, (Amount4 + 100) * 2, 0);
    CurrentPixel = saturationOp.Apply(CurrentPixel);

    // TODO: Add additional pixel processing code here
    int R = CurrentPixel.R;
    int G = CurrentPixel.G;
    int B = CurrentPixel.B;
    int A = CurrentPixel.A;

    if (Amount5)
    // Define the highest value for the alpha channel
    { A = Math.Max(Math.Max(R, G), В); }
      CurrentPixel.A = Int32Util.ClampToByte(A);

    dst[x, y] = CurrentPixel;
    }
  }
}

It's necessary to create an icon for the interface of our effect from the PNG file, which have the size of 16x16 pixels. I have created such icon: Neon-Egdes.png.

 

Now let's save our effect as a DLL file: File-> Save as DLL... Almost all information is in the dialog box, which presented to you. Click the Select icon link and select the icon. Click the Build button - your new effect is ready!

The user interface of our new effect looks like this.

 

UI-en.jpg

And this is the result of effect's work with a dark blue background, which was placed under the image.

 

Result-NE.jpg

I think, it was easy to create this effect.

Thanks to BoltBait for his advice about the hue and saturation. This allowed me to find a simple variant of the use of the hue and saturation for this tutorial.

 

Вариант этой темы на русском языке смотрите здесь.

Edited by ReMake
Images restored
  • Upvote 2
Link to comment
Share on other sites

picgifs-78-e6d575ffef95e2566388491eab84alfmdh6l7.png A lot of work but definitely worth it. Thank you very much for the effort and for the sharing.

Live as if you were to die tomorrow. Learn as if you were to live forever.

Gandhi

 

mae3426x.png

Link to comment
Share on other sites

 

On 3/22/2015 at 7:17 PM, Seerose said:

picgifs-78-e6d575ffef95e2566388491eab84alfmdh6l7.png A lot of work but definitely worth it. Thank you very much for the effort and for the sharing.

 

Thank You very much, Seerose! Laie_48.gif

 

Link to comment
Share on other sites

On 3/22/2015 at 8:14 PM, Red ochre said:

A colourful effect well explained - thank you!

 

Thank You very much, Red ochre! hi.gif

Link to comment
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.

×
×
  • Create New...