toe_head2001 Posted February 10, 2016 Share Posted February 10, 2016 (edited) When you use a custom Surface as the input for the Gaussian Blur effect, and have the radius set to 0, it will mess with the pixels outside of the selection on the left and right. Like so: And of course we all know modifying pixels outside the selection on the Destination canvas will break Undo. This issue can be seen in plugins like my 'Inset Box Shadow' plugin, and BoltBait's 'Inner Shadow (Selection)'. Just set the Blur to 0 in either of these plugins. I do not know if this is a new bug, or if it existed in old version of paint.net. In the mean time, I suppose I can just use an If statement to bypass the Gaussian Blur if the value is 0. --------- Here's a reduce code example demonstrating the bug. Run it on a selection. protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { if (customSurface == null) customSurface = new Surface(srcArgs.Surface.Size); customSurface.Clear(Color.Purple); base.OnSetRenderInfo(newToken, dstArgs, srcArgs); } void Render(Surface dst, Surface src, Rectangle rect) { // Setup for calling the Gaussian Blur effect GaussianBlurEffect blurEffect = new GaussianBlurEffect(); PropertyCollection blurProps = blurEffect.CreatePropertyCollection(); PropertyBasedEffectConfigToken BlurParameters = new PropertyBasedEffectConfigToken(blurProps); BlurParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, 0); blurEffect.SetRenderInfo(BlurParameters, new RenderArgs(dst), new RenderArgs(customSurface)); // Call the Gaussian Blur function blurEffect.Render(new Rectangle[1] {rect},0,1); } Edited February 10, 2016 by toe_head2001 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...
Rick Brewster Posted February 10, 2016 Share Posted February 10, 2016 This isn't really a bug. The valid range for the Radius property is [2, 200] as specified by the Property itself. If you want a proper range check then get the Property, cast to ScalarProperty<int>, and inspect its Min/MaxValue. 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...
BoltBait Posted February 10, 2016 Share Posted February 10, 2016 The built-in Gaussian Blur has a UI range of 0-200. As I recall, due to requests from us plugin authors, you added some special code to Gaussian Blur to handle the case of radius 0 where you do a copy surface. Apparently, this is a problem for non-rectangular selections in paint.net 4.0+. If possible, I'd really like you to keep this functionality available to us plugin authors. Lots of discussion about this "0" issue on pages 2-4 of this thread: http://forums.getpaint.net/index.php?/topic/6697- 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 February 10, 2016 Share Posted February 10, 2016 Oh, I actually read my code wrong. (2, 0, 200) is for (default, min, max). 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...
Rick Brewster Posted February 10, 2016 Share Posted February 10, 2016 Yeah there's a bug here. I actually consider there to be 2 bugs. The other bug is that the effect rendering system should not break like that if you render outside of the region of interest. HRESULT (__stdcall EffectKernel_GaussianBlur)( BitmapData* pDstBitmap, BitmapData* pSrcBitmap, const RectInt32* prcRoi, const int nRoisLen, const int nBlurRadius) { if (pDstBitmap == NULL || pSrcBitmap == NULL || prcRoi == NULL) { return E_POINTER; } if (pDstBitmap->scan0 == NULL || pSrcBitmap->scan0 == NULL) { return E_POINTER; } if (nBlurRadius == 0) { for (int i = 0; i < nRoisLen; ++i) { RectInt32 rect = prcRoi[i]; int cbRow = pDstBitmap->cbPixel * pDstBitmap->width; for (int y = rect.y; y < rect.y + rect.height; ++y) { void* pDst = pDstBitmap->GetRowAddress(y); void* pSrc = pSrcBitmap->GetRowAddress(y); CopyMemory(pDst, pSrc, cbRow); } return S_OK; } } ... 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...
BoltBait Posted February 10, 2016 Share Posted February 10, 2016 The "return S_OK;" is inside of the for loop? 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 February 10, 2016 Share Posted February 10, 2016 ummmmmmmmmmmmm that would be bug #3 ! O_O I was referring to the fact that it copies rows from dst into src without respecting the horizontal span of the rectangle. 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...
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.