Red ochre Posted April 10, 2012 Posted April 10, 2012 Recolour choice 8 differnt ways to select and replace a colour. There are many plugins allowing selection and replacement of colours and there are the built in tools, magic wand and recolor. These are all good and useful in different situations. However, I was working on a picture and found I couldn't select the region I wanted, so I decided to experiment with different algorithms. I have also included a 'blend' slider to soften the replaced colour. If you duplicate the layer first and select the 'keep unaltered selected' checkbox, you will be left with the selected region as an object on its own layer for further processing. Tip: It's easiest to use the ink dropper tool to select the desired detection colour before running the plugin. It is in my plugin pack here: Red ochre plugin pack Here's the codelab code if you want to play with the algorithms! This thread is relevant too http://forums.getpai...or-bucket-tool/ Hidden Content: /* =================================================== */ /* */ /* recolour choice */ /* (c) 2012 Red Ochre */ /* */ /* Description: colour replacement with more options */ /* */ /* ========================================== ======== */ // Name: recolour choice // Author: Red ochre (John Robbins) // Submenu: Color // URL: http://www.getpaint.net/redirect/plugins.html // Title: recolour choice April 2012 Red Ochre #region UICode byte Amount1 = 0; // colour detection method by:|H,S & V|B,G & R|Euclidean distance|tone (B + G + R) only|tone (HSV Value)only|Saturation only|Hue only|transparency value only (over-rides checkbox) ColorBgra Amount2 = ColorBgra.FromBgr(120,124,172); // colour to detect bool Amount3 = true; // [0,1] include transparency (alpha) in detection int Amount4 = 255; // [0,255] detection transparency double Amount5 = 10; // [0,100] detection tolerance % ColorBgra Amount6 = ColorBgra.FromBgr(255,0,0); // replacement colour int Amount7 = 255; // [0,255] replacement transparency double Amount8 = 0; // [0,100] blend edges bool Amount9 = false; // [0,1] keep unaltered detected only #endregion void Render(Surface dst, Surface src, Rectangle rect) { ColorBgra cp; int B, G, R,A,lum, B1,G1,R1,A1,lum1, B2,G2,R2,A2; double t1,t1b,t1p,t1d,t1e,t1l, t2, euc,euc1; for(int y = rect.Top; y < rect.Bottom; y++) { for (int x = rect.Left; x < rect.Right; x++) {cp = src[x,y];// cp = current pixel = set to source pixel B = cp.B;G = cp.G;R = cp.R;A = cp.A;// source pixel B1 = (int)Amount2.B;G1 = (int)Amount2.G;R1 = (int)Amount2.R;// colour to detect A1 = Amount4; // detection transparency from slider - not from primary t1 = Amount5/100; //detection tolerance t1b = t1 * 255;// t1 byte, from 0 to 255 but a double for easier maths! t1p = t1 * 100;// t1 percent, from 0 to 100 t1d = t1 * 360;// t1 degrees, from 0 to 360 t1e = t1 * 441.67;// Euclidean range t1l = t1 * 765;// tone/ lum range (255 * 3) t2 = Amount8/100; //blend tolerance B2 = (int)Amount6.B;G2 = (int)Amount6.G;R2 = (int)Amount6.R;// replacement colour from color wheel A2 = (int)Amount7;// replacement transparency from slider Color col = cp.ToColor();// from Boltbait's tutorial part4 - thanks BB! HsvColor hsv = HsvColor.FromColor(col);// source HSV color int H = hsv.Hue;// from 0 to 360 (Red,Orange,Yellow,Green,Turquoise,Blue,Magenta,Carmine) int S = hsv.Saturation;// from 0(grey) to 100 (full colour) int V = hsv.Value;// from 0 (black) to 100 (white) Color col1 = Amount2.ToColor(); HsvColor hsv1 = HsvColor.FromColor(col1);// detection HSV color int H1 = hsv1.Hue; int S1 = hsv1.Saturation; int V1 = hsv1.Value; double blend1 = 1;// have to assign a value double blend; double iblend; int Adiff = Math.Abs(A - A1);// declare here as used in many cases double Hdiff = Math.Abs(H - H1); double Sdiff = Math.Abs(S - S1); double Vdiff = Math.Abs(V - V1); switch (Amount1) { case 0:// by H,S & V if((Hdiff < t1d) &&(Sdiff < t1p) &&(Vdiff < t1p)) {if(!Amount3 ||(Amount3 && Adiff < t1b)) { blend1 = t2 * ((Hdiff / t1d) + (Sdiff / t1p) + (Vdiff / t1p)); } } break; case 1:// % change per colour int Bdiff = Math.Abs(B - B1);// declare here int Gdiff = Math.Abs(G - G1);// as only case int Rdiff = Math.Abs(R - R1);// to use them if(Bdiff < t1b && Gdiff < t1b && Rdiff < t1b) { if((Amount3 && Adiff < t1b)||!Amount3) { blend1 = t2 * (Bdiff + Gdiff + Rdiff) / t1b; } } break; case 2:// Euclidean // sqrt of (255 * 255 * 3 ) = 441.67 // 255 * 255 = 65025 euc = Math.Sqrt((B * + (G * G) + (R * R)) ; euc1 = Math.Sqrt((B1 * B1) + (G1 * G1) + (R1 * R1)); double eucdiff = Math.Abs(euc - euc1); if(eucdiff < t1e) { if((Amount3 && Adiff < t1b)||!Amount3) {blend1 = t2 * eucdiff / t1e;} } break; case 3:// B,G,R tone only (lum = approx luminance) lum = B + G + R;// source lum1 = B1 + G1 + R1;// primary color double lumdiff = Math.Abs(lum - lum1); if(lumdiff < t1l) {if((Amount3 && Adiff < t1b)||!Amount3) {blend1 = t2 * lumdiff / t1l;} } break; case 4:// (H,S,V tone)Value only if(Vdiff < t1p) { if(!Amount3 ||(Amount3 && Adiff < t1b)) { blend1 = t2 * Vdiff / t1p; } } break; case 5:// Saturation value only if(Sdiff < t1p) { if(!Amount3 ||(Amount3 && Adiff < t1b)) { blend1 = t2 * Sdiff / t1p; } } break; case 6:// Hue value only if(Hdiff < t1d) { if(!Amount3 ||(Amount3 && Adiff < t1b)) { blend1 = t2 * Hdiff/ t1d; } } break; case 7:// transparency only if(Adiff < t1b) { blend1 = t2 * Adiff/ t1b; } break; }// end of switch block if(blend1 > 1){blend1 = 1;}// to prevent colour reversal if more than 1 blend = 1 - blend1; // as in cases 1 & 7 iblend = 1 - blend; B = (int)((B2 * blend) + (B * iblend)); G = (int)((G2 * blend) + (G * iblend)); R = (int)((R2 * blend) + (R * iblend)); A = (int)((A2 * blend) + (A * iblend)); // keep unaltered detected - transparency srcA * blend if(Amount9){if(blend > 0){ B = src[x,y].B;G = src[x,y].G;R = src[x,y].R;A = (int)(src[x,y].A * blend);} if(blend == 0){A = 0;}} // Reassemble the color from B, G, and R cp = ColorBgra.FromBgra( Int32Util.ClampToByte(, Int32Util.ClampToByte(G), Int32Util.ClampToByte(R), Int32Util.ClampToByte(A)); dst[x,y] = cp; } } } 1 Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
Djisves Posted April 19, 2012 Posted April 19, 2012 Thank you Red ochre. Being able to play with different algorithms in addition to colour tolerance will certainly make life easier for a lot of users. The "keep unaltered" selection option is brilliant too. Quote
blackpenny Posted April 19, 2012 Posted April 19, 2012 Well, this is just cool! Recolor doesn't always work the way I want but this does. And I can get neat effects when I play with the tolerance and transparency. Thank you! Quote
nitenurse79 Posted April 19, 2012 Posted April 19, 2012 This will be useful, great plug-in redochre many thanks for your on going developing. Quote
Red ochre Posted April 19, 2012 Author Posted April 19, 2012 Hello Djisves, Blackpenny and Nitenurse. Many thanks for replying - it's very appreciated I'm glad you're finding it useful. Writing plugins is addictive you know! Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
Origami Posted July 22, 2012 Posted July 22, 2012 Hi Red ochre, Thanks for this neat plugin. I know Christmas is still a long time from now, but if I may write my wish list for this plugin, it would be : - On the top of the window, next to the RGB values, put the HSV values. (like in the Paint.NET color picker windows) so that the user can see both values (RGB and HSV). - Instead of having a Tolerance slider which applies to the 3 values, leave the possibility to have a tolerance for each value (RGB or HSV). And the Tolerance, instead of being in %, should be a threshold. For example you could say : I want to replace the colors with Hue = 130 (with a Threshold of 10, meaning that I can go from 120 to 140), and Saturation = 50 (with a threshold of 30 : I take all the values from 20 to 80) and Value = 10 (with a threshold of 40 : I take all the values from 0 to 50) I hope my description is clear. Thanks again for your great plugin. Quote
Red ochre Posted July 22, 2012 Author Posted July 22, 2012 Hello Origami, welcome to the forum. Thanks for the positive feedback. Re: the Christmas wish list (I can think of few things myself!), The color picker is generated by 'codelab' and is standard. It would be great if it offered the less/more option (showing HSV and alpha) like the main color window, but sadly it does'nt. A similar window could be created using Visual studio, but unfortunately that's too hard to use (for a simpleton like myself anyway). The other suggestion for seperate sliders for Hue, Saturation and Value, with corresponding integer tolerance sliders would be possible but would ideally be 'linked' to the BGR values (again something that can only be done in Visual studio). Also adding 6 more sliders would make the interface massive. So I won't be changing this plugin. It would however be relatively easy to create a simpler plugin that only does the specific task you described (using codelab). Probably easiest to have one plugin just for HSV and another just for BGR. eg/ 3 HSV sliders, 3 tolerance sliders, a BGR color picker for the replacement colour? - or use the secondary color as replacement (easiest)? - or 3 HSV sliders and a transparency slider for the replacement? (It would be tricky to show the detection colour range from the HSV values on the interface, but a checkbox could be used to show this on an area of the image [uncheck before rendering].) I have included the codelab code above and I'd like to encourage you to download codelab and have a go at altering my code to suit your needs. Read BoltBait's tutorials first and see how you get on. If you really need this, and I get the time, I'll see what Santa can do. All the best Quote Red ochre Plugin pack.............. Diabolical Drawings ................Real Paintings
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.