pascal Posted July 1, 2020 Share Posted July 1, 2020 (edited) [April 22th 2023] Version 2 available! Back with my second plugin. This time I made a plugin that can be used to easily and quickly create a gradient mapping effect using 2 colors. I know pyrochild already made a gradient mapping tool, but this is just a simplified version using only 2 colors for dark and light tones. I added some options for post processing as well, like contrast and blending mode. Download Location: Effects > Color > Duotone Gradient Map duotonegradientmap.zip Code Spoiler #region UICode ColorWheelControl DARK = ColorBgra.FromBgr(0, 0, 0); // Dark ColorWheelControl LIGHT = ColorBgra.FromBgr(255, 255, 255); // Light IntSliderControl CONTRAST = 0; // [-100,100] Contrast ListBoxControl<BlendMode> BLEND = 0; // Blending mode|Normal IntSliderControl MIX = 100; // [0,100] Mix #endregion enum BlendMode { Normal, Multiply, Screen, Darken, Lighten, Overlay, Additive } Func<byte, byte, byte> blender = null; void PreRender(Surface dst, Surface src) { blender = BLEND switch { BlendMode.Multiply => BlendMult, BlendMode.Screen => BlendScreen, BlendMode.Darken => BlendDarken, BlendMode.Lighten => BlendLighten, BlendMode.Overlay => BlendOverlay, BlendMode.Additive => BlendAdd, _ => BlendNormal }; } void Render(Surface dst, Surface src, Rectangle rect) { double mix = MIX / 100.0; double contrast = CONTRAST / 10.0; ColorBgra c; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; for (int x = rect.Left; x < rect.Right; x++) { c = src[x,y]; double value = Contrast((c.R + c.G + c.B) / 765.0, contrast); ColorBgra n = Mix(DARK, LIGHT, value); n = ApplyBlend(c, n, blender); n = Mix(c, n, mix); n.A = c.A; dst[x,y] = n; } } } double Contrast(double x, double p) { if (p == 0) { return x; } if (p > 0) { return x < 0.5 ? 0.5 * Math.Pow(2.0 * x, p + 1.0) : 1.0 - 0.5 * Math.Pow(2.0 - 2.0 * x, p + 1.0); } else { return x < 0.5 ? 0.5 - 0.5 * Math.Pow(1.0 - 2.0 * x, 1.0 - p) : 0.5 + 0.5 * Math.Pow(2.0 * x - 1.0, 1.0 - p); } } ColorBgra Mix(ColorBgra a, ColorBgra b, double value) { return ColorBgra.FromBgr( Mix(a.B, b.B, value), Mix(a.G, b.G, value), Mix(a.R, b.R, value) ); } byte Mix(byte a, byte b, double value) { double output = (1.0 - value) * a + value * b; return (byte) Math.Clamp(output, 0.0, 255.0); } ColorBgra ApplyBlend(ColorBgra a, ColorBgra b, Func<byte, byte, byte> f) { return ColorBgra.FromBgr( f(a.B, b.B), f(a.G, b.G), f(a.R, b.R) ); } byte BlendNormal(byte a, byte b) { return b; } byte BlendDarken(byte a, byte b) { return Math.Min(a, b); } byte BlendLighten(byte a, byte b) { return Math.Max(a, b); } byte BlendMult(byte a, byte b) { return (byte) Math.Clamp(a * b * 0.0039215686, 0.0, 255.0); } byte BlendScreen(byte a, byte b) { return (byte) (255 - BlendMult((byte) (255 - a), (byte) (255 - b))); } byte BlendOverlay(byte a, byte b) { return (byte) (a < 127 ? 2 * BlendMult(a, b) : 2 * BlendScreen(a, b)); } byte BlendAdd(byte a, byte b) { return (byte) Math.Clamp(a + b, 0, 255); } Edited April 22, 2023 by pascal effect location 2 1 1 Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted July 1, 2020 Share Posted July 1, 2020 //BLENDING MODES //multiply if(M == 1){ You could clean up the code using Switch /Case for these tests. switch (M) { case 1: //Console.WriteLine("Case 1"); break; case 2: //Console.WriteLine("Case 2"); break; ... default: //Console.WriteLine("Default case"); break; } It's not a big thing - but BoltBait & toe_head2001 have got some awesome coloring effects for sliders baked right into Codelab. They look really cool 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 July 2, 2020 Share Posted July 2, 2020 1 hour ago, Ego Eram Reputo said: You could clean up the code using Switch /Case for these tests. Using an enum is even cleaner. #region UICode ListBoxControl<BlendingMode> blendingMode = 0; // Blending mode|Normal|Multiply|Darken|Lighten|Additive #endregion enum BlendingMode { Normal, Multiply, Darken, Lighten, Additive } void Render(Surface dst, Surface src, Rectangle rect) { switch (blendingMode) { case BlendingMode.Multiply: // code here break; case BlendingMode.Darken: // code here break; case BlendingMode.Lighten: // code here break; case BlendingMode.Additive: // code here break; case BlendingMode.Normal: default: // code here break; } } 1 2 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...
TrevorOutlaw Posted July 2, 2020 Share Posted July 2, 2020 I wanted to make a plugin very similar to this at one time. Awesome plugin! Quote Link to comment Share on other sites More sharing options...
Vagabondi Posted December 1, 2020 Share Posted December 1, 2020 Works like charm @pascal. Endless possibilities to recolor photo - and very good settings. Quote my gallery is here Link to comment Share on other sites More sharing options...
Panchdara Posted December 1, 2020 Share Posted December 1, 2020 @pascal - Nice. Whilst the "suggestions" are constructive, you've built some code that can be used. There's always a critic. Your code is entirely readable. Stick with what you feel comfortable with. Quote Link to comment Share on other sites More sharing options...
pascal Posted April 22, 2023 Author Share Posted April 22, 2023 Version 2 available - Changed the layout to make it more clear in which order things are applied. - Contrast now only applies to the color-mapped layer. - Added more blending modes. - Made the mix slider independent of blending modes. - Improved overall code. 1 2 Quote 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.