Jump to content
How to Install Plugins ×

Increase Local Contrast effect plugin


MichaelVinther

Recommended Posts

MODERATORS NOTE:  This effect is incompatible with Paint.NET 4.0x, and was replaced by Laplacian pyramid filter.

https://forums.getpaint.net/topic/24563-laplacian-pyramid-filter-effect-plugin/

 

 

Increase local contrast can improve badly lit photos. It can also give a dramatic effect to otherwise dull pictures. Decreasing the filter size will increase the local contrast and color saturation. Note that the filter tend to amplify any noise in the picture (especially with small filter and high contrast settings) so it can be a good idea to apply noise reduction before the operation.
I think that this kind of filter is sometimes referred to as a retinex filter. The effect is also similar to what you can achieve with HDR software.

Example:

KievContrastBefore.jpgKievContrastAfter.jpg

Download version 1.2.0.0 (2012-04-06):

http://meesoft.com/P...calContrast.zip

 

IncreaseLocalContrast.zip

Unzip the file in the Paint.NET\Effects folder.

You can access the feature from the Effects | Photo menu.

 

Edited by toe_head2001

Michael Vinther

Link to comment
Share on other sites

Not to be too picky but this would be great with a "review" button so that I could check back with the original pic while using it. Great plugin, at first I thought it was gonna be like the "Local Contrast Enhancement" plugin but it's not. It's seems like this is gonna help a lot with my current project of replicating HDR images with Paint.net

Puteulanus___Jake2k_by_Club_PaintDotNET.png

^Click to visit my Flickr Gallery^

Link to comment
Share on other sites

Maybe it is best you put the dll in a zip file. Some firewalls don’t allow people to download dll’s.

EDIT: Plug-in works good. :D

Leif is correct. Please zip the file. (and use .ZIP, please, not .7Z or .RAR or anything...)

 

The Doctor: There was a goblin, or a trickster, or a warrior... A nameless, terrible thing, soaked in the blood of a billion galaxies. The most feared being in all the cosmos. And nothing could stop it, or hold it, or reason with it. One day it would just drop out of the sky and tear down your world.
Amy: But how did it end up in there?
The Doctor: You know fairy tales. A good wizard tricked it.
River Song: I hate good wizards in fairy tales; they always turn out to be him.

Link to comment
Share on other sites

Mine encountered a bug and PDN restarted. =X

codeembersig.png

-I may have not been here when you passed away, but you will be missed.-

Link to comment
Share on other sites

Ok, I have added a ZIP download.

This is my very first PDN plugin (and one of my first C# projects...) - just took an afternoon to do it. I thought about making a Show original button to make it easy to compare but I didn't know how. I will try to find out..

If you see any crashes please let me know if it happens with a special kind of image or if you have any other idea what triggered it.

Michael Vinther

Link to comment
Share on other sites

So we try again - this time without using Parallel Extensions (and without multicore optimization).

You do realize that Paint.NET's effect renderer is already multithreaded? Your OnRender() method is already multithreaded, unless you specifically tell Paint.NET to work in single threaded mode.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Also, you should really use IndirectUI instead of implementing your own dialog. You've just got two sliders, there's really no reason to implement all of your own data binding and layout.

Derive from PropertyBasedEffect instead, and go from there.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Ok, thanks for the hint about the dialog. The example plugin I based mine on just had an empty form so I assumed that I had to make the GUI from scratch.

About multithreading, it is not that simple. My algorithm is a multi-pass IIR filter so I cannot just compute any pixel independant of the others. Actually everything is computed the first time Render() is called with a new parameter token in a lock() { } section so any following calls (in the same thread or others) will just return pixels. This is why the progress bar appears to stop for a long time at 0%.

Michael Vinther

Link to comment
Share on other sites

leave it to me to somehow mess something up:

Error Report:

  • File: C:\Program Files\Paint.NET\Effects\IncreaseLocalContrast.dll
    Effect Name: MeeSoft.Paint.Net.Plugins.IncreaseLocalContrast.EffectPlugin
    Full error message: PaintDotNet.WorkerThreadException: Worker thread threw an exception ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
    File name: 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
    at MeeSoft.ImageProcessing.PlanarBitmap.New(Int32 planeCount, Double gamma)
    at MeeSoft.ImageProcessing.PlanarBitmap.New(Int32 width, Int32 height, Int32 planeCount, Double gamma)
    at MeeSoft.ImageProcessing.PlanarBitmap.Assign(Bitmap source)
    at MeeSoft.Paint.Net.Plugins.IncreaseLocalContrast.EffectOperation.CheckParams(EffectPluginConfigToken param, Bitmap srcBitmap)
    at MeeSoft.Paint.Net.Plugins.IncreaseLocalContrast.EffectPlugin.Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, Int32 startIndex, Int32 length)
    at PaintDotNet.Effects.BackgroundEffectRenderer.ThreadFunction()
    WRN: Assembly binding logging is turned OFF.
    To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
    Note: There is some performance penalty associated with assembly bind failure logging.
    To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
    --- End of inner exception stack trace ---
    at PaintDotNet.Effects.BackgroundEffectRenderer.Join()
    at PaintDotNet.Effects.BackgroundEffectRenderer.Start()
    at PaintDotNet.Menus.EffectMenuBase.<>c__DisplayClassb.b__8(Object sender, EventArgs e)

Link to comment
Share on other sites

It looks like this plugin requires .NET version 3.5, which you either don't have or your installation is not right.

I could be wrong -- I just gathered that from a quick glance at the crash log.

xZYt6wl.png

ambigram signature by Kemaru

[i write plugins and stuff]

If you like a post, upvote it!

Link to comment
Share on other sites

leave it to me to somehow mess something up:

You need to install .NET Framework 3.5 SP1. I'll add this to the plugin details at the top.

Edit: Just noticed he already spelled this out. But, my edit makes it more obvious :)

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Ok, thanks for the hint about the dialog. The example plugin I based mine on just had an empty form so I assumed that I had to make the GUI from scratch.

About multithreading, it is not that simple. My algorithm is a multi-pass IIR filter so I cannot just compute any pixel independant of the others. Actually everything is computed the first time Render() is called with a new parameter token in a lock() { } section so any following calls (in the same thread or others) will just return pixels. This is why the progress bar appears to stop for a long time at 0%.

Hi Michael,

This could be worth a read: Buffered Graphics

Link to comment
Share on other sites

Looks like alternative to Shadow/highlight recovery...

I thought about making a Show original button to make it easy to compare but I didn't know how. I will try to find out..
You can check for exampe here.

In my version the review button is bound to a check box that triggers Identity() pixel op when checked.

If you decide to go for IndirectUI then you could simply add a check box "Show original" where checked state would return original.

Here is the relevant part of my code:

Hidden Content:
...
private UnaryPixelOps.Identity Nop = new UnaryPixelOps.Identity(); // this op returns original image when "Review" button is pressed

       public override unsafe void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length)
       {
           ...
           bool check = token.checkBox2; // that's linked to Review button pressed state
           ...
           Surface dst = dstArgs.Surface;
           Surface src = srcArgs.Surface;

           if (check == false) // "REVIEW" BUTTON IS PRESSED -> ORIGINAL IMAGE IS SHOWN
           {
               Nop.Apply(dst, src, rois, startIndex, length);
           }

           else  // "REVIEW" BUTTON IS NOT PRESSED -> EFFECT IS RUNNING
           {
           ...

BTW, are you the guy who created Image Analyzer?

I have learnt a lot of things whith that program, really appreciate! :)

Link to comment
Share on other sites

Ok, thanks for all of your suggestions. I have released a new version of the plugin (same download link as above).

News:


  • [*:3466sfj6] There is now a button called "Original" which you can hold to show the source image.
    [*:3466sfj6] The menu item appears in the correct menu also for non-english versions of PDN
    [*:3466sfj6] The filter size default was changed to 30 for a more distinct result

Also, you should really use IndirectUI instead of implementing your own dialog. You've just got two sliders, there's really no reason to implement all of your own data binding and layout.

Derive from PropertyBasedEffect instead, and go from there.

I tried this, but the GUI did not behave as nice as I can make it with my own dialog. Have a look at my comment to this topic in the development forum.

BTW, are you the guy who created Image Analyzer?

Yes, I am. The Increase Local Contrast effect also exists in IA but with a few more options. I have considered making more of the features from IA available as plugins for PDN.

Michael Vinther

Link to comment
Share on other sites

Could anyone please write the correct string for the Photo submenu? I mean the localizeable version.

It's already there in the SubmenuNames static class. He just needs to use it.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

I tried this, but the GUI did not behave as nice as I can make it with my own dialog. Have a look at my comment to this topic in the development forum.

And I just replied :)

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

I'm afraid there's a rendering bug. I used it on a 1280x8xx image and aftwerwards it looked like it was splited in parts and put together in a wrong way. Apparently it happens when your zoom is set to 100%.

The bug was reproduceable, but sometimes you need to look closely.

Link to comment
Share on other sites

Ok, I fixed the rendering problem. It happened only when the zoom was 100% for some reason, so I didn't notice it before.

Michael Vinther

Link to comment
Share on other sites

Ok, I fixed the rendering problem. It happened only when the zoom was 100% for some reason, so I didn't notice it before.

Thanks. I'd also ask you to add the publishing date of the current version to your first post, like 2009/03/23, instead of just a version number like 1.0.1.1. It's pretty hard to say if something has changed if it's like 1.0.1.0 to 1.0.1.1. Especially imagine someone has holidays, comes back and cannot tell wether something has changed or not. If you see that the current version was published on, say 09/03/30, you won't have to guess.

Link to comment
Share on other sites

Thanks for the plugin - works very nicely. Appreciate the presence of a button to see the original photo state but is there a way to resume applying the plugin effect after reverting to the original state?

Link to comment
Share on other sites

Oops! Apologies but I've re-read the first post again and realize that the original photo state stays on only when the mouse is held down. Thanks for the plugnin.

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