Keanny Ooi Posted April 28, 2020 Share Posted April 28, 2020 Hi there! I'm new to plugin coding and I would like to create a plugin that can blur a specific part of an image (not selected) just with a click of a button. Example: https://imgur.com/a/9LPCstX Here is a random image of a car. (file size too big so I had to resort to this) The selected area is exactly where I want to blur. What I want to do is that this specific area (it's ok if the selected area looks weird, I know how to break it up) is applied with Gaussian blur of 70 every time I press the button, regardless of whether or not that area is selected. It should look like this after pressing the button: https://imgur.com/a/899z9C2 Any help is much appreciated since I am just starting out. Thanks! -Keanny (P.S.: first post here) Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted April 28, 2020 Share Posted April 28, 2020 Why not use Copy Selection and Paste Selection? Also, if you're asking about implementing a plugin then your question goes into the Plugin Developer's Central. I'm moving your post. 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Keanny Ooi Posted April 29, 2020 Author Share Posted April 29, 2020 14 hours ago, Rick Brewster said: Why not use Copy Selection and Paste Selection? Also, if you're asking about implementing a plugin then your question goes into the Plugin Developer's Central. I'm moving your post. Yes, that's what I meant. Sorry about that. First time posting here so I don't know which goes where. Quote Link to comment Share on other sites More sharing options...
Keanny Ooi Posted April 30, 2020 Author Share Posted April 30, 2020 UPDATE: I figured out how to apply Gaussian blur of 70 to the entire image. Now I just have to narrow it down to that selected area. I'm thinking about trying to get the coordinates of every single pixel during pixel processing, how should I do that? (mock up) Example: if (CurrentPixel.Coordinates.X >= 1064 || CurrentPixel.Coordinates.Y <= 96) { // idk what im doing here // apply gaussian blur here } Is there such property for CurrentPixel? Thanks in advance. -Keanny Quote Link to comment Share on other sites More sharing options...
NSD Posted April 30, 2020 Share Posted April 30, 2020 (edited) Hi @Keanny OoiYou can play with the little plugin below. Instead of Help you have the code, so click the button '?'. You can copy it with Ctrl + A / Ctrl + C and then paste it into CodeLab to make the change as you wish. Edited May 3, 2020 by NSD Quote Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 1, 2020 Author Share Posted May 1, 2020 For some reason i got this error message: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at PaintDotNet.SystemLayer.PdnNativeMethods.x64.EffectKernel_GaussianBlur(PdnBitmapData& dstBitmap, PdnBitmapData& srcBitmap, Rectangle* pRois, Int32 roisLength, Int32 blurRadius) at PaintDotNet.SystemLayer.RenderingKernels.GaussianBlur(BitmapData dstBitmap, BitmapData srcBitmap, Rectangle[] rois, Int32 startIndex, Int32 length, Int32 blurRadius) in D:\src\pdn\src\SystemLayer\RenderingKernels.cs:line 521 at PaintDotNet.Effects.GaussianBlurEffect.OnRender(Rectangle[] rois, Int32 startIndex, Int32 length) in D:\src\pdn\src\Effects\GaussianBlurEffect.cs:line 141 at TDCEffect.TDCEffectPlugin.Render(Surface dst, Surface src, Rectangle rect) at TDCEffect.TDCEffectPlugin.OnRender(Rectangle[] rois, Int32 startIndex, Int32 length) at PaintDotNet.Effects.Effect`1.Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, Int32 startIndex, Int32 length) in D:\src\pdn\src\Effects\Effect`1.cs:line 99 at PaintDotNet.Effects.BackgroundEffectRenderer.RenderWithClipMask(Effect effect, EffectConfigToken token, RenderArgs dstArgs, RenderArgs srcArgs, RectInt32[] rois, Result`1 lazyClipMaskRenderer) in D:\src\pdn\src\PaintDotNet\Effects\BackgroundEffectRenderer.cs:line 193 at PaintDotNet.Effects.BackgroundEffectRenderer.RendererContext.RenderTile(EffectConfigToken token, Int32 tileIndex) in D:\src\pdn\src\PaintDotNet\Effects\BackgroundEffectRenderer.cs:line 173 at PaintDotNet.Effects.BackgroundEffectRenderer.RendererContext.RenderNextTile(EffectConfigToken token) in D:\src\pdn\src\PaintDotNet\Effects\BackgroundEffectRenderer.cs:line 165 at PaintDotNet.Effects.BackgroundEffectRenderer.ThreadFunction() in D:\src\pdn\src\PaintDotNet\Effects\BackgroundEffectRenderer.cs:line 283 --- End of inner exception stack trace --- at PaintDotNet.Effects.BackgroundEffectRenderer.DrainExceptions() in D:\src\pdn\src\PaintDotNet\Effects\BackgroundEffectRenderer.cs:line 458 at PaintDotNet.Menus.EffectMenuBase.DoEffect(Effect effect, EffectConfigToken token, Result`1 lazySelectionScans, Result`1 lazyRegionToRenderScans, Result`1 lazyClipMaskRenderer, Surface originalSurface, Exception& exception) in D:\src\pdn\src\PaintDotNet\Menus\EffectMenuBase.cs:line 0 This is causing the plugin to not work at all. Here is my modified script: // Setup for calling the Gaussian Blur effect GaussianBlurEffect gaussianblurEffect = new GaussianBlurEffect(); PropertyCollection gaussianblurProps; protected override void OnDispose(bool disposing) { if (disposing) { // Release any surfaces or effects you've created if (gaussianblurEffect != null) gaussianblurEffect.Dispose(); gaussianblurEffect = null; } base.OnDispose(disposing); } void PreRender(Surface dst, Surface src) { // Gaussian Blur gaussianblurEffect.EnvironmentParameters = EnvironmentParameters; gaussianblurProps = gaussianblurEffect.CreatePropertyCollection(); PropertyBasedEffectConfigToken gaussianblurParameters = new PropertyBasedEffectConfigToken(gaussianblurProps); gaussianblurParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, 70); gaussianblurEffect.SetRenderInfo(gaussianblurParameters, new RenderArgs(dst), new RenderArgs(src)); } void Render(Surface dst, Surface src, Rectangle rect) { dst.CopySurface(src, rect.Location, rect); Rectangle sel = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); int sT = sel.Top; int sB = sel.Bottom; int sL = sel.Left; int sR = sel.Right; int x = 1064; int y = 96; Point left = new Point(sL, sT + x); Point rite = new Point(sR, sT + x); Point top = new Point(y + sL, sT); Point bot = new Point(y + sL, sB); int w = sR - sL; int h = left.Y - sT; Rectangle r1 = new Rectangle(0, 0, w, h); w = sR - top.X; h = sB - sT; Rectangle r2 = new Rectangle(top.X, 0, w, h);; // Now call the Gaussian Blur function from src surface to dst surface gaussianblurEffect.Render(new Rectangle[1] {r1},0,1); gaussianblurEffect.Render(new Rectangle[1] {r2},0,1); } Other than that, thanks for the code that you provided me! Quote Link to comment Share on other sites More sharing options...
NSD Posted May 1, 2020 Share Posted May 1, 2020 (edited) The error is given by the fact that the maximum value of the sliders does not correspond to the length / width of the canvas. Using CodeLab it is not possible to load these maximum values at runtime with the values of the canvas. Edited May 1, 2020 by NSD typo Quote Link to comment Share on other sites More sharing options...
Reptillian Posted May 1, 2020 Share Posted May 1, 2020 (edited) 2 hours ago, NSD said: The error is given by the fact that the maximum value of the sliders does not correspond to the length / width of the canvas. Using CodeLab it is not possible to load these maximum values at runtime with the values of the canvas. Could it be possible to add a conditional to bypass that error? Edited May 1, 2020 by Reptillian Quote G'MIC Filter Developer I am away from this forum for undetermined amount of time: If you really need anything related to my PDN plugin or my G'MIC filter within G'MIC plugin, then you can contact me via Paint.NET discord, and mention me. Link to comment Share on other sites More sharing options...
BoltBait Posted May 1, 2020 Share Posted May 1, 2020 OP, try this CodeLab script: // Name: Blur Corner // Author: BoltBait // Version: 1.0 #region UICode IntSliderControl Amount1 = 70; // [0,100] Gaussian Blur Radius IntSliderControl TopPercent = 20; // [0,100] Blur Top Percent IntSliderControl RightPercent = 20; // [0,100] Blur Right Percent #endregion // Setup for calling the Gaussian Blur effect GaussianBlurEffect gaussianblurEffect = new GaussianBlurEffect(); PropertyCollection gaussianblurProps; protected override void OnDispose(bool disposing) { if (disposing) { // Release any surfaces or effects you've created if (gaussianblurEffect != null) gaussianblurEffect.Dispose(); gaussianblurEffect = null; } base.OnDispose(disposing); } // This single-threaded function is called after the UI changes and before the Render function is called // The purpose is to prepare anything you'll need in the Render function void PreRender(Surface dst, Surface src) { // Gaussian Blur gaussianblurEffect.EnvironmentParameters = EnvironmentParameters; gaussianblurProps = gaussianblurEffect.CreatePropertyCollection(); PropertyBasedEffectConfigToken gaussianblurParameters = new PropertyBasedEffectConfigToken(gaussianblurProps); gaussianblurParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, Amount1); gaussianblurEffect.SetRenderInfo(gaussianblurParameters, new RenderArgs(dst), new RenderArgs(src)); } // Here is the main multi-threaded render function // The dst canvas is broken up into rectangles and // your job is to write to each pixel of that rectangle void Render(Surface dst, Surface src, Rectangle rect) { // Now call the Gaussian Blur function from src surface to dst surface gaussianblurEffect.Render(new Rectangle[1] {rect},0,1); // Step through each row of the current rectangle for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; // Step through each pixel on the current row of the rectangle for (int x = rect.Left; x < rect.Right; x++) { ColorBgra CurrentPixel = dst[x,y]; ColorBgra SourcePixel = src[x,y]; if ((x < src.Width * (100-RightPercent) / 100) && (y > src.Height * TopPercent / 100)) { CurrentPixel = SourcePixel; } dst[x,y] = CurrentPixel; } } } Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game Link to comment Share on other sites More sharing options...
Rick Brewster Posted May 1, 2020 Share Posted May 1, 2020 It also looks like you're switching x and y ? int x = 1064; int y = 96; Point left = new Point(sL, sT + x); // uhh, the second parameter is Y, why're you doing +x ? Point rite = new Point(sR, sT + x); // same here Point top = new Point(y + sL, sT); // and the opposite here Point bot = new Point(y + sL, sB); // same here 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 2, 2020 Author Share Posted May 2, 2020 (edited) No, I delete the UI stuff and basically it would automatically set the Gaussian blur to 70, and apply it to a fixed place. All in a press of a button. There are no constraints at all. Edited May 2, 2020 by Keanny Ooi Additional info that might be useful Quote Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 3, 2020 Author Share Posted May 3, 2020 (edited) UPDATE: After some improvising using BoltBait's code, I finally did it! Thank you everyone for your help! Also quick question: Are paint.net plugins capable of inserting pictures into the canvas? Example: https://imgur.com/a/Y3AhvhK Here is a picture. Let's say i want to insert another picture into said picture, all within a press of a button. It should look like this after pressing the button: https://imgur.com/a/raFmwdY Is this possible? EDIT: @BoltBait, is it possible to print out bold text using the DrawString function? -Keanny Edited May 4, 2020 by Keanny Ooi asking something real quick Quote Link to comment Share on other sites More sharing options...
BoltBait Posted May 4, 2020 Share Posted May 4, 2020 On 5/3/2020 at 12:12 AM, Keanny Ooi said: EDIT: @BoltBait, is it possible to print out bold text using the DrawString function? Here is some source code showing how to do it: https://forums.getpaint.net/topic/111330-unfinished-plugins/?do=findComment&comment=543199 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 4, 2020 Author Share Posted May 4, 2020 4 hours ago, BoltBait said: Here is some source code showing how to do it: https://forums.getpaint.net/topic/111330-unfinished-plugins/?do=findComment&comment=543199 Thanks a lot! I feel like there should be a code reference for CodeLab, that way it can be easier for beginners. btw one more question, is it possible to change the alignment of the text while printing it? Example: you set the alignment to the right, text goes to the right as more text is added. you set the alignment to the left, text goes to the left as more text is added. you set the alignment to the middle, text goes to the middle as more text is added. -Keanny Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted May 5, 2020 Share Posted May 5, 2020 There are dozens of tutorials like this one: Dragan Effect - codelab first steps Then there are a set of awesome tuts by @BoltBait here BoltBait.com For more, try using the forum search tool Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
toe_head2001 Posted May 5, 2020 Share Posted May 5, 2020 11 hours ago, Keanny Ooi said: Thanks a lot! I feel like there should be a code reference for CodeLab, that way it can be easier for beginners. btw one more question, is it possible to change the alignment of the text while printing it? While in CodeLab, click on the DrawString method, and press F12 on your keyboard. That will take you to the appropriate page on docs.microsoft.com, where you can read the relevant documentation. To answer your question: Yes. Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 5, 2020 Author Share Posted May 5, 2020 4 hours ago, toe_head2001 said: While in CodeLab, click on the DrawString method, and press F12 on your keyboard. That will take you to the appropriate page on docs.microsoft.com, where you can read the relevant documentation. To answer your question: Yes. Thanks a lot! Here are more questions: 1. (was asked before but no one answered) On 5/3/2020 at 3:12 PM, Keanny Ooi said: Are paint.net plugins capable of inserting pictures into the canvas? Example: https://imgur.com/a/Y3AhvhK Here is a picture. Let's say i want to insert another picture into said picture, all within a press of a button. It should look like this after pressing the button: https://imgur.com/a/raFmwdY Is this possible? 2. Here is a string of words. I would like it so that the unbolded text's location depends on how long the bolded text is. Let's say I changed the bolded text to this random meme. The word "there" should move to the right side a little bit because the meme word is longer than the word "Hello". If the bolded word is shorter, the unbolded text should move to the left a little bit. TL, DR: The spacing between the bolded word and the unbolded one remains the same. Is this possible? If so, how? -Keanny Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted May 5, 2020 Share Posted May 5, 2020 On 5/3/2020 at 7:12 AM, Keanny Ooi said: Also quick question: Are paint.net plugins capable of inserting pictures into the canvas? Example: https://imgur.com/a/Y3AhvhK Here is a picture. Let's say i want to insert another picture into said picture, all within a press of a button. It should look like this after pressing the button: https://imgur.com/a/raFmwdY Is this possible? Yes, there are a methods. If you tell how you want it to work, and we can give you details how to do it. 7 minutes ago, Keanny Ooi said: TL, DR: The spacing between the bolded word and the unbolded one remains the same. Is this possible? If so, how? Take a look at MeasureString. For the non-paint.net-specific stuff, please look on the Microsoft Docs site or stackoverflow. Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Keanny Ooi Posted May 6, 2020 Author Share Posted May 6, 2020 On 5/5/2020 at 1:45 PM, toe_head2001 said: Yes, there are a methods. If you tell how you want it to work, and we can give you details how to do it. I would like it to work like a stamp tool that stamps the picture in place, with the anchor set in the middle. I would like the pic to be stored inside the plugin. It should also allow the picture to be exchanged with another one. Not sure if it is feasible or not? As for the MeasureString thing, thanks a lot! I sure will do my searching in the Microsoft docs before asking here! Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted May 6, 2020 Share Posted May 6, 2020 Start with creating a Surface from your image. Surface mySurface = Surface.CopyFromBitmap(myBitmap); If you're looking for sample code, there's tons of it inside of CodeLab. Inside CodeLab, go to File -> New. Also look here: https://forums.getpaint.net/tags/source code/ (There are many more, they just haven't been tagged yet) 4 minutes ago, Keanny Ooi said: I would like the pic to be stored inside the plugin. It's possible to have an image file embedded into your plugin, but not with CodeLab. You'd have to switch to Visual Studio. Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted May 7, 2020 Share Posted May 7, 2020 So why not use some of the tools already created? I know @Reptillian has something similar to this in the G'Mic plugin. Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.