Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by Tanel

  1. Thank you guys!

    Ed, I got your point, blur effect requires complete source image before start, but in my case it receives source image strip by strip, hence distorted results.

    pyrochild, does your Film plugin contain complete workaround for this?

    If so, then I'm a bit confused of Ed's comment:

    • ...
      [*:1vbysz8a]Even if you were to find a way to create a work surface only once (a dispose of it in a timely fashion), you will never have the full image available for the blur.

    I will study your Film plugin code thoroughly, very helpful indeed!

    Did I guess the sequence of six main operations correctly?

    Could you kindly explain logic of the tricks implemented there, six places I marked with "???":

    ... // comments by Tanel:
    protected override void OnRender(Rectangle[] rois, int startIndex, int length)
               OnRenderCalled = true;
               if (SetRenderInfoCalled) // ???
                   zbe.Render(rois, startIndex, length); // 1. Apply ZoomBlurEffect from srcArgs to dstArgs
                   baca.Render(rois, startIndex, length); // 2. Apply BrightnessAndContrastAdjustment from dstArgs to dstArgs
                   PdnRegion selection = EnvironmentParameters.GetSelection(SrcArgs.Bounds);
                   if (changed && grainoverlay != null) // ???
                       grainoverlay.Dispose(); // ???
                       grainoverlay = null; // ???
                   if (grainoverlay == null) // ???
                       Rectangle[] gorois = selection.GetRegionScansInt(); // build new surface "grainoverlay"
                       grainoverlay = new Surface(SrcArgs.Size);
                           grainoverlay.Clear(ColorBgra.Black); // apply black color to surface "grainoverlay"
                           goArgs = new RenderArgs(grainoverlay); // RenderArgs for surface "grainoverlay"
                           ane.SetRenderInfo(aneToken1, goArgs, goArgs);
                           ane.Render(gorois, 0, gorois.Length); // 3. render AddNoiseEffect on "grainoverlay" (from goArgs to goArgs)
                           changed = false; // ???
                       ane.SetRenderInfo(aneToken2, goArgs, goArgs); // (*)
                       mbe.SetRenderInfo(mbeToken, goArgs, goArgs); // (**)
                   } mbe.Render(rois, startIndex, length); // 4. render MotionBlurEffect (**) on "grainoverlay" 
                   ane.Render(rois, startIndex, length); // 5. render second AddNoiseEffect (*) on "grainoverlay" 
                   dbo.Apply(DstArgs.Surface, grainoverlay, rois, startIndex, length);  // 6. DifferenceBlendOp - grainoverlay (goArgs) over DstArgs


  2. Hi,

    I'm trying to implement GaussianBlurEffect for final touch-up of alpha values in my effect plugin (feathering, basically).

    To accomplish this, I built extra surface where core of my effect is rendered,

    then I call GaussianBlurEffect to render from tempSurface to dstArgs.

    The problem is that blur effect comes out distorted.

    Zoomed-up screenshots below.

    Instead of turning this (original):


    to this (desired effect):


    I get this (distortion):


    Amount of distortion varies by size of selection,

    so I guess I have some bounds misalignment going on, but I couldn't diagnose the exact cause.

    Can you point out what's wrong here? I'm completely stuck in this... :?

    Simplified code sample from VS2005:

           public override unsafe void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length)
               // BUILD A SURFACE "tempSurface" FOR BACKROUND RENDER
               Size surfaceSize = new Size(srcArgs.Surface.Width, srcArgs.Surface.Height);
               Surface tempSurface = new Surface(surfaceSize);
               RenderArgs temp = new RenderArgs(tempSurface);
               // CALL THE BACKROUND RENDER ON tempSurface
               RenderAlpha(parameters, tempSurface, srcArgs, rois, startIndex, length);
               EffectPluginConfigToken token = (EffectPluginConfigToken)parameters;
               PdnRegion selectionRegion = EnvironmentParameters.GetSelection(srcArgs.Bounds);
               Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Bounds).GetBoundsInt();
               // RENDER BLUR FROM tempSurface TO dstArgs
               PropertyBasedEffectConfigToken blurToken = new PropertyBasedEffectConfigToken(this.blurProps);
               blurToken.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, token.Feather);
               this.blurEffect.SetRenderInfo(blurToken, dstArgs, temp);
               base.OnSetRenderInfo(blurToken, dstArgs, temp);
               this.blurEffect.Render(rois, startIndex, length);
               for (int i = startIndex; i < startIndex + length; ++i)
                   Rectangle roi = rois[i];
                   for (int y = roi.Top; y < roi.Bottom; ++y)
                       ColorBgra* dstPtr = dstArgs.Surface.GetPointAddress(roi.X, roi.Y);
                       ColorBgra NewPixel;
                       ColorBgra OrigPixel;
                       byte a, ro, go, bo, ry, by, gy, ay;
                       for (int x = roi.Left; x < roi.Right; ++x)
                           NewPixel = dstArgs.Surface[x, y];
                           //r = NewPixel.R;
                           //g = NewPixel.G;
                           //b = NewPixel.B;
                           a = NewPixel.A; // THIS SHOULD BE BLURRED ALPHA
                           if (selectionRegion.IsVisible(x, y))
                               OrigPixel = srcArgs.Surface[x, y];
                               ro = OrigPixel.R;
                               go = OrigPixel.G;
                               bo = OrigPixel.B;
                               //ao = OrigPixel.A;
                               // FINAL PIXEL TO CONSIST OF ORIGINAL RGB + BLURRED ALPHA:
                               ry = Utility.ClampToByte(ro);
                               gy = Utility.ClampToByte(go);
                               by = Utility.ClampToByte(bo);
                               ay = Utility.ClampToByte(a);
                               NewPixel = ColorBgra.FromBgra(by, gy, ry, ay);
                               *dstPtr = NewPixel;
           // BACKROUND RENDER
           private unsafe void RenderAlpha(EffectConfigToken parameters, Surface surface, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length)
               EffectPluginConfigToken token = (EffectPluginConfigToken)parameters;
               for (int i = startIndex; i < startIndex + length; ++i)
                   Rectangle roi = rois[i];
                   for (int y = roi.Top; y < roi.Bottom; ++y)
                       ColorBgra* ptr = surface.GetPointAddress(roi.X, roi.Y);
                       ColorBgra OrigPixel;
                       byte ro, go, bo, ao, ry, by, gy, ay;
                       for (int x = roi.Left; x < roi.Right; ++x)
                           OrigPixel = srcArgs.Surface[x, y];
                           ro = OrigPixel.R;
                           go = OrigPixel.G;
                           bo = OrigPixel.B;
                           ao = OrigPixel.A;
                           ry = Utility.ClampToByte(ro);
                           gy = Utility.ClampToByte(go);
                           by = Utility.ClampToByte(bo);
                           ay = Utility.ClampToByte(ro); // GET ALPHA FROM RED IN THIS SAMPLE
                           OrigPixel = ColorBgra.FromBgra(by, gy, ry, ay);
                           *ptr = OrigPixel;

  3. ...

    I noticed, though, it doesn't keep shadows, just like the curves+ method I used above.

    I his original post, agent007bond says:

    Basically I should be able to remove the background colour (of my choice) and go back to the transparent version (top left) without losing shadow and translucency (partly transparent pixels at edges).

    Do you think it's possible to implement this (without too much work, I mean)?

    It is possible to keep shadows, by playing around with saturation and brightness limiters.


    But making the shadow semi-transparent is not yet possible (I'm adding Fade control for this).

    In order to desaturate the shadow, you should use Conditional Hue/Saturation plugin.

  4. Just out of interest what more are you thinking (hoping) of adding to the plug-in in the future. Personally i would recommend incorporating the "Feather" plug-in"feather" plug-in from BoltBait or the "Anti-alias" plug-in from jsonchiu in future editions.


    Thx for feedback, Geoff.

    I will definitely add Amount control for backround transparency.

    Second I add Fade control for smooth alpha fall-off through hue/saturation/brightness channels.

    But Feather seems to be tricky to implement. Because I already pre-render blur effect for Tolerance control. Maybe I figure out something. Final version has still long way to go.

  5. As a coincidence, I have been developing similar plugin for some weeks.

    You can try this "draft" version: Link

    (it is not yet fine enough to be published in plugins section)

    My basic idea for this plugin is to extract certain color range from image, by making surrounding pixels transparent. Hence the name Tone Picker.

    "Invert" mode should give you the "chroma key" effect.

    The plugin uses primary color to define it's default color range.

    So: I recommend to use color picker tool *before* opening the plugin - to define your color of interest.

    By default this plugin will extract pixels with hue P+-30, saturation P+-20, brightness P+-50 (P for primary color).

    You can override the input parameters by moving hue, saturation and brightness controls.

    Tolerance control makes selection more "rough" by ignoring fine details.

    Please comment.

  6. BoltBait,

    it seems that there is a bug:

    if original pixel is semi-transparent (with alpha whatever between 0 - 255) then Alpha Blur reduces original alpha before blurring. For example: evenly semi-transparent area with alpha 127 becomes to alpha 62 (the lower the radius, the lower it goes).

    Can you fix it so that original alpha would remain untouched?

    P.S. Can you also increase max radius to 200?



  7. Got a bug: most of plugins don't load on my XP laptop anymore...

    Problem solved! It was all my own bad... :oops:

    Please excuse me for this BS.

    I was studying evanolds' source code of conditional hue/saturation effect in C#, and apparently rebuild command dropped PaintDotNet.Core.dll and PaintDotNet.StylusReader.dll into the Effects folder. Just had to delete those and everything works normally again.

    Thanks MadJik and Fisherman's Friend for pointing me towards solution.

  8. :idea: hmm ok then so if im doing a mixed image of text,drawn art and panels (comic book) is it better to save it as .png for web viewing or .jpg

    It will be a web based comic book so thats what im concerned about..i read how .jpg is better for photos and that I knew but I have never saved anything with a .png format before

    I would recommend to publish this kind of stuff in .GIF format. You will get the smallest file sizes without remarkable loss.

    PNGs are huge, you dont want viewers to wait for images downloading.

    Make both gif and png copies of your art and compare for yourself.

    Some information here: http://www.wfu.edu/~matthews/misc/jpg_v ... VsGif.html

  9. Plugin Error:

    File: C:\Program Files\Paint.NET\Effects\ShadowHighlight.dll

    Effect Name: ShadowHighlight.EffectPlugin

    Full error message: PaintDotNet.WorkerThreadException: Worker thread threw an exception ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.

    Parameter name: 0 is not a valid value for Radius

    at PaintDotNet.PropertySystem.Property.set_Value(Object value)

    at PaintDotNet.Effects.PropertyBasedEffectConfigToken.SetPropertyValue(Object propertyName, Object newValue)

    at PaintDotNet.Effects.BlurEffect.OnSetRenderInfo(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs)

    at PaintDotNet.Effects.BlurEffect.Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, Int32 startIndex, Int32 length)

    at ShadowHighlight.EffectPlugin.Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, Int32 startIndex, Int32 length)

    at PaintDotNet.Effects.BackgroundEffectRenderer.ThreadFunction()

    --- End of inner exception stack trace ---

    at PaintDotNet.Effects.BackgroundEffectRenderer.Join()

    at PaintDotNet.Effects.BackgroundEffectRenderer.Start()

    at PaintDotNet.Menus.EffectMenuBase.<>c__DisplayClassa.b__8(Object sender, EventArgs e)

    Rick, do I need to revise my code?

    Shadow/Highlight plugin uses minimum gaussian blur radius 0 - just because it is possible in PDN 3.10. Why not in 3.20?

  10. Using Auto level made the blood a bit too dark. :idea: :?

    I didn't want to take all fun away :wink:

    I would fix the blood by copying the spots on a new layer (with magic wand);

    then open adjustments->levels:

    clear R channel check box and turn the middle output slider down to 3.0 (G and B channels only)

    check R channel and clear B&G

    Rise the middle output slider up to 0.5 (R channel only)


    then play with layer opacity for final touch.

  11. Slight problem with the control heights here:

    tdue, I could not reproduce your problem under any circumstances. It must be a fault in your system.

    Seeing the strange blue button sitting next to red close-button in your screenshot, I guess it's your graphics card's extended display functions not working well with your OS. Try disabling those functions if you don't desperately need them (nview, hydravision or whatever they call this piece of software).

    Any chance of a source code for this amazing plug-in?

    Yes, in some time.

  12. Anyone interested to contribute my plugins development?

    Please help me to edit this code carcass into working PdN effect C# code, so that I could use blurred RGBA values in further effect calculations. My skills are too weak to re-code it.

    I want to boost the performance of my Sharpen+ and ShadowHighlight plugins by replacing Gaussian blur with much faster one (I hope that fast blur's visual quality is good enough for that purpose). Unfortunately there is no built-in fast blur effect in PdN.

    There is another implementation with a link to source code here.


  13. Hey dudes!

    I've got a new idea for the SaturationZeroProblem:

    An Interface with 3 Sliders whcih set how important for the difference the channel should be. (i.e. with Value Importance = 100% and both other = 0% only the brightness of the pixel would be important)

    But you can't set the Hue importance but only the maximal hue importance. And the less Saturation a pixel has the less Hue will be important. So there would be no sharp edges.

    Anyone understood what I just said?

    Please feedback (good idea/understood nothing/bad idea)

    I would recommend to test it yourself. If YOU find it useful for some real operation then it should be okay.

  14. Nice pic, BoltBait!

    I'm definately loving the beginner mode. 8)

    it does most of the job for me too.

    Hi everyone! I agree this is an awesome plugin, similar to the one I use in HP photo printing, just more detailed. The only problem I have run into is that it takes forever to render the changes I make with it. Are my computer settings off (more virtual ram needed, not pressing the review button correctly, etc.) or is this due to the way the plugin was coded (I think I read in another thread a plugin took too long to render due to the source code). Any advice would be helpful. Thanks! :D

    I am using a Dell 4400, pentium 4 processor, 1.7ghz, 256 ram, nvidia geforce 2 graphics card.

    Yes, this plugin is heavy on resources, due to Gaussian blur being part of the algorithm (@ radius 12 in Basic mode).

    In my PC it takes few sec to render 800x600 image, but about 30 sec for 6MP image (1.73GHz, 504MB RAM).

    More RAM should speed up any photo editing remarkably. Graphics card doesn't matter as effect computing goes on in CPU+RAM only.

    For faster workflow you could use a resized copy (or small selection) of your image to find suitable settings, run the effect once to load settings into memory, then open original image and run the effect with just OK-ing the presets.

    I would really like to implement fast blur instead of Gaussian but haven't found good chance to do it. I wish there would be Fast Blur effect built in PDN, then we could call it from plugins with just 1 line of code.

  • Create New...