BoltBait 3,312 Posted June 9, 2014 Share Posted June 9, 2014 Hue / Saturation Plus This plugin is for Paint.NET 4.0+ only. It will not work on v3.5.11 or below, sorry. NOTE: User evanolds has made a more feature rich version of this plugin.* I am releasing this as a demonstration for how to add slider decorations to 4.0 plugins.** *evanolds plugin can be found here: http://forums.getpaint.net/index.php?/topic/13003-a **Read the tutorial here: http://forums.getpaint.net/index.php?/topic/28423-a That said, here's what it looks like: Download Users can download here: BoltBait's Plugin Pack for Paint.NET v4.0+ I think the best way to get used to how this effect works is to play with this using a picture of a color wheel. That way you'll see how the condition works. The adjustments work exactly the same as the built-in Hue / Saturation effect. Programmer's Section Programmers can download the CodeLab script here: Spoiler // Title: BoltBait's Hue / Saturation Plus v4.1 // Name: Hue / Saturation Plus // Submenu: Photo // URL: http://boltbait.com/pdn/ // Author: BoltBait // Version: 4.1 // Desc: Conditional Hue/Saturation Adjustment // Keywords: Conditional|Hue|Saturation|Adjustment #region UICode IntSliderControl Amount1 = 0; // [0,360,1] {!Amount10} From Hue IntSliderControl Amount2 = 360; // [0,360,1] {!Amount10} To Hue CheckboxControl Amount3 = false; // [0,1] {!Amount10} Also select gray pixels IntSliderControl Amount4 = 0; // [0,100,3] {!Amount10} From Saturation IntSliderControl Amount5 = 100; // [0,100,3] {!Amount10} To Saturation IntSliderControl Amount6 = 0; // [-180,180,2] {!Amount10} Hue Adjustment IntSliderControl Amount7 = 0; // [-100,100,3] {!Amount10} Saturation Adjustment IntSliderControl Amount8 = 0; // [-100,100,5] {!Amount10} Lightness Adjustment IntSliderControl Amount9 = 0; // [-100,100,5] {!Amount10} Alpha Adjustment CheckboxControl Amount10 = false; // [0,1] Preview original image #endregion int loc = -1; byte Clamp2Byte(double Value) { if (Value > 255) return 255; if (Value < 0) return 0; return (byte)Value; } private UnaryPixelOps.HueSaturationLightness saturationOp; private UnaryPixelOps.HueSaturationLightness graySatOp; unsafe void Render(Surface dst, Surface src, Rectangle rect) { if (Amount10) { dst.CopySurface(src, rect.Location, rect); return; } bool GrayCond = Amount3; int FromHue = Amount1; int ToHue = Amount2; bool ReverseHueCond = false; int FromSat = Amount4; int ToSat = Amount5; bool ReverseSatCond = false; if (FromHue > ToHue) { int TempHue = FromHue; FromHue = ToHue; ToHue = TempHue; ReverseHueCond = true; } if (FromSat > ToSat) { int TempSat = FromSat; FromSat = ToSat; ToSat = TempSat; ReverseSatCond = true; } saturationOp = new UnaryPixelOps.HueSaturationLightness(Amount6, Amount7+100, Amount8); graySatOp = new UnaryPixelOps.HueSaturationLightness(0, 100, Amount8); for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { ColorBgra CurrentPixel = *srcPtr; byte R = CurrentPixel.R; byte G = CurrentPixel.G; byte B = CurrentPixel.B; int K = (int)((double)CurrentPixel.R / 255d * 100d); HsvColor hsv = HsvColor.FromColor(CurrentPixel.ToColor()); int H = hsv.Hue; int S = hsv.Saturation; int V = hsv.Value; byte A = CurrentPixel.A; // Adjust only if not gray if (R != G || R != B || G != B) { if (CurrentPixel.A > 0) { // Check if we're in selected Hue range if ((H >= FromHue && H <= ToHue) != ReverseHueCond) { // and selected saturation range if ((S >= FromSat && S <= ToSat) != ReverseSatCond) { // adjust the pixel CurrentPixel = saturationOp.Apply(CurrentPixel); // adjust pixel alpha if (Amount9 < 0) { CurrentPixel.A = Clamp2Byte((double)CurrentPixel.A + ((double)CurrentPixel.A * ((double)Amount9 / 100.0))); } else if (Amount9 > 0) { CurrentPixel.A = Clamp2Byte((double)CurrentPixel.A + (((255 - (double)CurrentPixel.A) * (double)Amount9 / 100.0))); } } } } } else { if (CurrentPixel.A > 0) { // Adjust if gray if (GrayCond) { // adjust a gray pixel CurrentPixel = graySatOp.Apply(CurrentPixel); // adjust pixel alpha if (Amount9 < 0) { CurrentPixel.A = Clamp2Byte((double)CurrentPixel.A + ((double)CurrentPixel.A * ((double)Amount9 / 100.0))); } else if (Amount9 > 0) { CurrentPixel.A = Clamp2Byte((double)CurrentPixel.A + (((255 - (double)CurrentPixel.A) * (double)Amount9 / 100.0))); } } } } *dstPtr = CurrentPixel; srcPtr++; dstPtr++; } } } Download the Visual Studio project here: HueSatPlusSrc.zip Enjoy 5 Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to post Share on other sites
BoltBait 3,312 Posted June 11, 2014 Author Share Posted June 11, 2014 I have updated this plugin to implement a new feature. Now, when you select the "Preview original image" check box, the other sliders are disabled. This is a visual reminder that you are not changing the image in any way. Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to post Share on other sites
barbieq25 1,166 Posted June 12, 2014 Share Posted June 12, 2014 Very useful plugin BB! Many thanks for your hard work Quote Knowledge is no burden to carry. April Jones, 2012 Gallery My DA Gallery Link to post Share on other sites
MJW 1,354 Posted March 26, 2016 Share Posted March 26, 2016 I like this plugin very much, and use it quite often, but I wish it had "From Value/To Value" (or "From Lightness/To Lightness") controls. Quote Link to post Share on other sites
BoltBait 3,312 Posted March 26, 2016 Author Share Posted March 26, 2016 I like this plugin very much, and use it quite often, but I wish it had "From Value/To Value" (or "From Lightness/To Lightness") controls. Thanks! The UI is getting pretty long as it is. But, something like that shouldn't be too hard to add. This plugin is actually on my list for a rewrite. So, after I finish my current project, I'll give it a go. BTW, have you checked out the evanolds plugin I linked to in my original post? It may have the controls you're searching for. (It's been so long since I played with it, I can't remember.) Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to post Share on other sites
MJW 1,354 Posted March 27, 2016 Share Posted March 27, 2016 Thanks BoltBait. I haven't tried evanolds's Hue/Saturation plugin, but maybe I'll look at it. For the most part, Hue/Saturation+ does everything I need it to do, even without the Lightness range. There have been occasions, though, when Lightness controls would have been useful. Quote Link to post Share on other sites
Cc4FuzzyHuggles 320 Posted March 27, 2016 Share Posted March 27, 2016 Would it be possible for this plugin to use paint.net's primary and secondary colors? This plugin re-colors things very nicely, but often I wish it could re-color with the choice of using my primary or secondary color. Quote *~ Cc4FuzzyHuggles Gallery ~* Link to post Share on other sites
MJW 1,354 Posted March 27, 2016 Share Posted March 27, 2016 Cc4FuzzyHuggles, in IndirectUI there's no way to set controls to specific values, except to the default values, so I doubt Hue/Saturation+ could support multiple color choices while still using the range-slider interface. A similar control that uses a specified color and tolerances (like the HSV Eraser) could do it. That would probably be a useful plugin, but it wouldn't have the often-convenient ability to directly select the ranges. (I hope that's relatively clear.) Quote Link to post Share on other sites
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.