Sign in to follow this  
BoltBait

Combined Photo Adjustments - With source code (Jan 19, 2010)

Recommended Posts

I was processing a large set of photos the other day and was getting frustrated that I needed to run 4-5 different effects on each photo. I thought that all of these adjustments should be on the same UI so that I could just run one effect. So, that's what I built. (Nothing new here, just a combination of a bunch of effects.)

PhotoAdjustmentsUI.png

It saved me a ton of time processing those photographs as the sliders were remembered between each run.

Hopefully you'll find this useful too.

To install, download this file to your C:/Program Files/Paint.NET/Effects folder and unzip it. :PlusButton:

Download here

Tested with Paint.NET version 3.36 and above.

Here's the CodeLab source:

// Author: BoltBait
// Submenu: Photo
// Name: Combined Adjustments
// URL: http://www.BoltBait.com/pdn
// Title: BoltBait's Photo Adjustments v1.1
#region UICode
double Amount1 = 0.2; // [0,1] Noise Reduction
int Amount2 = -10; // [-100,100] Brightness
int Amount3 = 10; // [-100,100] Contrast
int Amount4 = 1; // [-10,10] Yellow                                                      Blue
int Amount5 = 5; // [-100,100] Saturation
int Amount6 = 30; // [0,100] Final Multiply Adjustment
#endregion

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

// Rick, stop moving stuff around!
private byte Clamp2Byte(int iValue)
{
    if (iValue<0) return 0;
    if (iValue>255) return 255;
    return (byte)iValue;
}

unsafe void Render(Surface dst, Surface src, Rectangle rect)
{
    Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
    saturationOp = new UnaryPixelOps.HueSaturationLightness(0, 100+Amount5, 0);
    
    // Setup for calling the Noise Reduction function
    ReduceNoiseEffect noiseEffect = new ReduceNoiseEffect();
    PropertyCollection nProps = noiseEffect.CreatePropertyCollection();
    PropertyBasedEffectConfigToken nParameters = new PropertyBasedEffectConfigToken(nProps);
    nParameters.SetPropertyValue(ReduceNoiseEffect.PropertyNames.Radius, 10);
    nParameters.SetPropertyValue(ReduceNoiseEffect.PropertyNames.Strength, Amount1);
    noiseEffect.SetRenderInfo(nParameters, new RenderArgs(dst), new RenderArgs(src));
    // Call the Reduce Noise function
    noiseEffect.Render(new Rectangle[1] {rect},0,1);

    // Setup for calling the Brightness and Contrast function
    BrightnessAndContrastAdjustment bacAdjustment = new BrightnessAndContrastAdjustment();
    PropertyCollection cProps = bacAdjustment.CreatePropertyCollection();
    PropertyBasedEffectConfigToken cParameters = new PropertyBasedEffectConfigToken(cProps);
    cParameters.SetPropertyValue(BrightnessAndContrastAdjustment.PropertyNames.Brightness, Amount2);
    cParameters.SetPropertyValue(BrightnessAndContrastAdjustment.PropertyNames.Contrast, Amount3);
    bacAdjustment.SetRenderInfo(cParameters, new RenderArgs(dst), new RenderArgs(dst));
    // Call the Brightness and Contrast function
    bacAdjustment.Render(new Rectangle[1] {rect},0,1); 

    // Now in the main render loop, the dst canvas has a fixed up 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++)
        {
            // Boost the saturation
            *dstPtr = saturationOp.Apply(*dstPtr);
            // Yellow-Blue adjustment
            ColorBgra SourcePixel = *dstPtr;
            SourcePixel.R = Clamp2Byte(SourcePixel.R - Amount4/2);
            SourcePixel.G = Clamp2Byte(SourcePixel.G - Amount4/2);
            SourcePixel.B = Clamp2Byte(SourcePixel.B + Amount4);
            *dstPtr = SourcePixel;
            // Finally, add a little "punch" to the overall picture
            ColorBgra DestPixel = *dstPtr;
            DestPixel.A = (byte)(int)(Amount6 * 255.0 / 100.0);
            *dstPtr = multiplyOp.Apply(*dstPtr, DestPixel);

            srcPtr++;
            dstPtr++;
        }
    }
} 
 

This is now included in my plugin pack.

  • Upvote 1

Share this post


Link to post
Share on other sites

Really cool! It would be pretty awesome if there was a slider that controlled the Portrait plugin of yours and the reverse effect. I find it useful, but mostly because it gives me more source code to go over. Good plugin and idea, and I would recommend packaging it if others feel the same :P

Share this post


Link to post
Share on other sites
Whenever I go to use it, It comes up with an error and i have to restart paint.net..

This plugin requires the latest build of Paint.NET. Upgrade Paint.NET and it should work fine.

Share this post


Link to post
Share on other sites
Whenever I go to use it, It comes up with an error and i have to restart paint.net..

This plugin requires the latest build of Paint.NET. Upgrade Paint.NET and it should work fine.

For some reason ive always been hesistant to download the new version..Whats the difference and where can i download it?

Share this post


Link to post
Share on other sites
Whenever I go to use it, It comes up with an error and i have to restart paint.net..

This plugin requires the latest build of Paint.NET. Upgrade Paint.NET and it should work fine.

This is no longer true.

I recompiled the plugin against Paint.NET 3.36 so you should download it again and it will work with your version of Paint.NET.

Share this post


Link to post
Share on other sites
I immediately thought of Tanel's Photo Adjustments. But I see yours has quite different functions.

I can see that I'd use both frequently. I love that you have supplied the source!

Did you consider including a "sharpen" feature?

Yes, mine is quite different from Tanel's. :)

I usually don't need to sharpen my indoor photos (which this is designed for) since the focus is not set to infinity.

I did include a sharpen function in my Landscape plugin (which is designed for outdoor photos). Have you tried that?

Share this post


Link to post
Share on other sites

I can see usefulness for landscaping picture (working in tandem with Landscape plugin) or to improve texture that I plan to make soon (if I ever find the time...)

Reading the source code made me cross-eyed, but I was wondering what effects did you pull together to make this plugin?

*downloads*

Share this post


Link to post
Share on other sites
Reading the source code made me cross-eyed, but I was wondering what effects did you pull together to make this plugin?

OK, this is a combination of the following controls (top to bottom):

1. The Strength slider from the Effects > Noise > Reduce Noise effect

2&3. The Brightness and Contrast sliders from the Adjustments > Brightness/Contrast effect

4. The Yellow-Blue slider from my Adjustments > Color Balance plugin

5. The Saturation slider from the Adjustments > Hue/Saturation effect

6. Um... This last slider actually simulates the following:

-Duplicate the layer

-Change the top duplicate layer to blend mode Multiply

-This slider is now the Opacity slider of the top duplicate layer's property box

Basically, it functions like a Contrast adjustment for Saturation.

Clear? ;)

Share this post


Link to post
Share on other sites

It is as clear as a chocolate pie on the back of a wet elephant.

Thanks though for taking the time to explain how it works. Now that I have the information, I'm sure to fire it up soon, and crank out some photomanips.

Share this post


Link to post
Share on other sites
I usually don't need to sharpen my indoor photos (which this is designed for) since the focus is not set to infinity.

That makes perfect sense.

I did include a sharpen function in my Landscape plugin (which is designed for outdoor photos). Have you tried that?

I have both Sharpen and Sharpen+ installed and usually dive straight for those. To be honest I doubt I'd look to your Landscape plugin for a sharpen unless I was also using some of the other features as well.

Thanks for this plugin. It will be very useful! 8)

Share this post


Link to post
Share on other sites

Thanks for this, Boltbait! It's useful in and of itself as a single consolidated way to make a number of adjustments, and the source code is a great example of how to compose effects (and by composition, I mean function composition).

Share this post


Link to post
Share on other sites
Thankyou for allowing it to be used in the older version of paint.net :)

Umm ... why don't you just install the latest version of Paint.NET :? :?:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this