Jump to content

Landscape Plugin - With source code (Nov 2, 2009)

Recommended Posts

Tomorrow is my birthday, but today you get the present!

Remember when I wrote the Portrait plugin, MadJik wrote:

MadJik said:

Another good plugin :plugin: ! I like it ! Thanks...

=>joke : ETA for Landscape plugin ?

Well, ETA is TODAY! :D



It automates a bunch of steps that I make when fixing landscape pictures. It is obviously not right for everything, but I find it useful. Hopefully you will too.

Download the Landscape.dll as part of my plugin pack here: https://forums.getpaint.net/index.php?/topic/32048-v

If you have trouble installing this plugin, post your troubles here.

Enjoy. B)

For those that are interested in such things, here is the CodeLab source:

// Author: BoltBait
// Submenu: Photo
// Name: Sharpen Landscape
// URL: http://www.BoltBait.com/pdn
#region UICode
Pair<double, double> Amount1 = Pair.Create( 0.0 , -0.25 ); // Position of Horizon
int Amount2 = 50; // [0,100] Sky
int Amount3 = 50; // [0,100] Grass
int Amount4 = 100; // [0,200] Sharpen
int Amount5 = 50; // [0,100] Saturation
int Amount6 = 50; // [0,100] Final Multiply Adjustment

// Setup for using the various blend ops
private UserBlendOps.OverlayBlendOp overlayOp = new UserBlendOps.OverlayBlendOp();
private UserBlendOps.ColorDodgeBlendOp dodgeOp = new UserBlendOps.ColorDodgeBlendOp();
private UserBlendOps.MultiplyBlendOp multiplyOp = new UserBlendOps.MultiplyBlendOp();
private UnaryPixelOps.HueSaturationLightness saturationOp;

unsafe void Render(Surface dst, Surface src, Rectangle rect)
    Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    ColorBgra Sky = ColorBgra.FromBgr(255,128,0);
    ColorBgra Grass = ColorBgra.FromBgr(0,128,0);
    int HorizonRow = (int)Math.Round(((Amount1.Second + 1) / 2) * (selection.Bottom - selection.Top));
    saturationOp = new UnaryPixelOps.HueSaturationLightness(0, 100+Amount5*3, 0);

    // Setup for calling the Blur function
    GaussianBlurEffect blurEffect = new GaussianBlurEffect();
    PropertyCollection bProps = blurEffect.CreatePropertyCollection();
    PropertyBasedEffectConfigToken bParameters = new PropertyBasedEffectConfigToken(bProps);
    bParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, 1);
    blurEffect.SetRenderInfo(bParameters, new RenderArgs(dst), new RenderArgs(src));
    // Call the Blur function
    blurEffect.Render(new Rectangle[1] {rect},0,1);

    // Now in the main render loop, the dst canvas has a blurred version of the src canvas
    for (int y = rect.Top; y < rect.Bottom; y++)
        ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y);
        ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
        for (int x = rect.Left; x < rect.Right; x++)
            // Create a blue gradient at the top
            if (< HorizonRow) {
                Sky.= (byte)(int)((255.0 - (255.0 * y / HorizonRow ))*(Amount2/100.0));
            } else {
                Sky.= (byte)0;

            // Create a green gradient at the bottom
            if (> HorizonRow) {
                Grass.= (byte)(int)((255.0 * (y-HorizonRow) / (selection.Bottom-HorizonRow))*(Amount3/100.0));
            } else {
                Grass.= (byte)0;

            ColorBgra AdjustmentPixel = *dstPtr;
            ColorBgra SourcePixel = *srcPtr;

            // Sharpen (unsharp mask)
            double NewR = (double)SourcePixel.+ ((double)SourcePixel.- (double)AdjustmentPixel.R) * (double)Amount4 / 100.0;
            double NewG = (double)SourcePixel.+ ((double)SourcePixel.- (double)AdjustmentPixel.G) * (double)Amount4 / 100.0;
            double NewB = (double)SourcePixel.+ ((double)SourcePixel.- (double)AdjustmentPixel.B) * (double)Amount4 / 100.0;
            AdjustmentPixel.= Utility.ClampToByte(NewR);
            AdjustmentPixel.= Utility.ClampToByte(NewG);
            AdjustmentPixel.= Utility.ClampToByte(NewB);

            // Boost the saturation
            *dstPtr = saturationOp.Apply(AdjustmentPixel);

            // Add in the sky and grass
            *dstPtr = multiplyOp.Apply(*dstPtr, Sky);
            *dstPtr = dodgeOp.Apply(*dstPtr, Grass);

            // Finally, add a little "punch" to the overall picture
            AdjustmentPixel = *dstPtr;
            AdjustmentPixel.= (byte)(int)(Amount6 * 255.0 / 100.0);
            *dstPtr = multiplyOp.Apply(*dstPtr, AdjustmentPixel);


Thanks to Tanel for the Sharpen (unsharp mask) code.

  • Upvote 3

Click to play:
Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game

Link to post
Share on other sites
  • 2 months later...

I really like this plugin.

BoltBait is there any way to have a tilt option for the horizon line? sometimes the horizon just isn't smack dab across the screen in straight line.

the work around I've been using is larger canvas and rotating the image then applying plugin then re righting the picture. not absolutlely ideal. but only way I can think to do this. is there another method I'm not thinking of?

ciao OMA

  • Upvote 1
Link to post
Share on other sites
  • 6 months later...
  • 6 years later...


In CodeLab:

1. CTRL+I and click on Update (the selected control)

2. Replace the original code:

AdjustmentPixel.R = Utility.ClampToByte(NewR);
AdjustmentPixel.G = Utility.ClampToByte(NewG);
AdjustmentPixel.B = Utility.ClampToByte(NewB);


AdjustmentPixel.R = Int32Util.ClampToByte((int)NewR);
AdjustmentPixel.G = Int32Util.ClampToByte((int)NewG);
AdjustmentPixel.B = Int32Util.ClampToByte((int)NewB);


  • Upvote 1
Link to post
Share on other sites

<3 Dear @ingwer


:trophy:  Thank you very much for the video and for your effort,  it's helped me. :cake: :coffee: 






*PS: The photo belongs to me. 

Edited by Seerose
  • Upvote 2

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




Link to post
Share on other sites
  • 1 year later...

Since you created CodeLab in the first place, could you teach me how to apply two effects in a plugin? I'm working on a HDR plugin and I'm trying to add a "Brightness/Contrast" effect to it before the "Gaussian Blur" effect - but I seem to get errors. Any tips and help?

Big McThankies From McSpankies!

sakana sig resized.png

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.

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...