ReMake Posted February 6, 2018 Share Posted February 6, 2018 (edited) It is very difficult to find the information about algorithms of blend modes in the Internet. pegtop.net and the blog by Andrey Zhuravlev in LiveJournal - two sites where I found the most detailed and the helpful information. Below is the fragments of the code for additional blend modes for paint.net written on the basis of the analysis of information from the websites shown above. All modes have been tested on similarity with blend modes of the Photoshop. In most cases results had the full coincidence, but sometimes results had a small difference. Spoiler case LinearBurn: byte LBR = Int32Util.ClampToByte(src[x, y].R + CurrentPixel.R - 255); byte LBG = Int32Util.ClampToByte(src[x, y].G + CurrentPixel.G - 255); byte LBB = Int32Util.ClampToByte(src[x, y].B + CurrentPixel.B - 255); CurrentPixel = ColorBgra.FromBgra(LBB, LBG, LBR, CurrentPixel.A); break; case SoftLight: byte SLR = Int32Util.ClampToByte((src[x, y].R * CurrentPixel.R >> 8) + src[x, y].R * (255 - ((255 - src[x, y].R) * (255 - CurrentPixel.R) >> 8) - (src[x, y].R * CurrentPixel.R >> 8)) / 255); byte SLG = Int32Util.ClampToByte((src[x, y].G * CurrentPixel.G >> 8) + src[x, y].G * (255 - ((255 - src[x, y].G) * (255 - CurrentPixel.G) >> 8) - (src[x, y].G * CurrentPixel.G >> 8)) / 255); byte SLB = Int32Util.ClampToByte((src[x, y].B * CurrentPixel.B >> 8) + src[x, y].B * (255 - ((255 - src[x, y].B) * (255 - CurrentPixel.B) >> 8) - (src[x, y].B * CurrentPixel.B >> 8)) / 255); CurrentPixel = ColorBgra.FromBgra(SLB, SLG, SLR, CurrentPixel.A); break; case HardLight: byte HLR = (CurrentPixel.R <= 128) ? Int32Util.ClampToByte(src[x, y].R * CurrentPixel.R >> 7) : Int32Util.ClampToByte(255 - ((255 - src[x, y].R) * (255 - CurrentPixel.R) >> 7)); byte HLG = (CurrentPixel.G <= 128) ? Int32Util.ClampToByte(src[x, y].G * CurrentPixel.G >> 7) : Int32Util.ClampToByte(255 - ((255 - src[x, y].G) * (255 - CurrentPixel.G) >> 7)); byte HLB = (CurrentPixel.B <= 128) ? Int32Util.ClampToByte(src[x, y].B * CurrentPixel.B >> 7) : Int32Util.ClampToByte(255 - ((255 - src[x, y].B) * (255 - CurrentPixel.B) >> 7)); CurrentPixel = ColorBgra.FromBgra(HLB, HLG, HLR, CurrentPixel.A); break; case VividLight: byte VLR, VLG, VLB; if (CurrentPixel.R <= 128) { VLR = ((src[x, y].R + 2 * CurrentPixel.R) >= 255) ? Int32Util.ClampToByte(((src[x, y].R - (255 - 2 * CurrentPixel.R)) * 255) / (2 * CurrentPixel.R + 1)) : (byte)(0); } else { VLR = ((src[x, y].R + 2 * (CurrentPixel.R - 128)) <= 255) ? Int32Util.ClampToByte((255 * src[x, y].R) / (255 - 2 * (CurrentPixel.R - 128))) : (byte)(255); } if (CurrentPixel.G <= 128) { VLG = ((src[x, y].G + 2 * CurrentPixel.G) >= 255) ? Int32Util.ClampToByte(((src[x, y].G - (255 - 2 * CurrentPixel.G)) * 255) / (2 * CurrentPixel.G + 1)) : (byte)(0); } else { VLG = ((src[x, y].G + 2 * (CurrentPixel.G - 128)) <= 255) ? Int32Util.ClampToByte((255 * src[x, y].G) / (255 - 2 * (CurrentPixel.G - 128))) : (byte)(255); } if (CurrentPixel.B <= 128) { VLB = ((src[x, y].B + 2 * CurrentPixel.B) >= 255) ? Int32Util.ClampToByte(((src[x, y].B - (255 - 2 * CurrentPixel.B)) * 255) / (2 * CurrentPixel.B + 1)) : (byte)(0); } else { VLB = ((src[x, y].B + 2 * (CurrentPixel.B - 128)) <= 255) ? Int32Util.ClampToByte((255 * src[x, y].B) / (255 - 2 * (CurrentPixel.B - 128))) : (byte)(255); } CurrentPixel = ColorBgra.FromBgra(VLB, VLG, VLR, CurrentPixel.A); break; case LinearLight: byte LLR = Int32Util.ClampToByte(src[x, y].R + 2 * CurrentPixel.R - 255); byte LLG = Int32Util.ClampToByte(src[x, y].G + 2 * CurrentPixel.G - 255); byte LLB = Int32Util.ClampToByte(src[x, y].B + 2 * CurrentPixel.B - 255); CurrentPixel = ColorBgra.FromBgra(LLB, LLG, LLR, CurrentPixel.A); break; case PinLight: byte PLR, PLG, PLB; if (CurrentPixel.R < 128) { PLR = (src[x, y].R <= (2 * CurrentPixel.R)) ? src[x, y].R : Int32Util.ClampToByte(2 * CurrentPixel.R); } else { PLR = (src[x, y].R >= (2 * (CurrentPixel.R - 128))) ? src[x, y].R : Int32Util.ClampToByte(2 * (CurrentPixel.R - 128)); } if (CurrentPixel.G < 128) { PLG = (src[x, y].G <= (2 * CurrentPixel.G)) ? src[x, y].G : Int32Util.ClampToByte(2 * CurrentPixel.G); } else { PLG = (src[x, y].G >= (2 * (CurrentPixel.G - 128))) ? src[x, y].G : Int32Util.ClampToByte(2 * (CurrentPixel.G - 128)); } if (CurrentPixel.B < 128) { PLB = (src[x, y].B <= (2 * CurrentPixel.B)) ? src[x, y].B : Int32Util.ClampToByte(2 * CurrentPixel.B); } else { PLB = (src[x, y].B >= (2 * (CurrentPixel.B - 128))) ? src[x, y].B : Int32Util.ClampToByte(2 * (CurrentPixel.B - 128)); } CurrentPixel = ColorBgra.FromBgra(PLB, PLG, PLR, CurrentPixel.A); break; case HardMix: byte HMR = Int32Util.ClampToByte((CurrentPixel.R < 255 - src[x, y].R) ? 0 : 255); byte HMG = Int32Util.ClampToByte((CurrentPixel.G < 255 - src[x, y].G) ? 0 : 255); byte HMB = Int32Util.ClampToByte((CurrentPixel.B < 255 - src[x, y].B) ? 0 : 255); CurrentPixel = ColorBgra.FromBgra(HMB, HMG, HMR, CurrentPixel.A); break; case Exclusion: byte ER = Int32Util.ClampToByte(src[x, y].R + CurrentPixel.R - (src[x, y].R * CurrentPixel.R >> 7)); byte EG = Int32Util.ClampToByte(src[x, y].G + CurrentPixel.G - (src[x, y].G * CurrentPixel.G >> 7)); byte EB = Int32Util.ClampToByte(src[x, y].B + CurrentPixel.B - (src[x, y].B * CurrentPixel.B >> 7)); CurrentPixel = ColorBgra.FromBgra(EB, EG, ER, CurrentPixel.A); break; case Subtract: byte SR = Int32Util.ClampToByte(src[x, y].R - CurrentPixel.R); byte SG = Int32Util.ClampToByte(src[x, y].G - CurrentPixel.G); byte SB = Int32Util.ClampToByte(src[x, y].B - CurrentPixel.B); CurrentPixel = ColorBgra.FromBgra(SB, SG, SR, CurrentPixel.A); break; case Divide: // not full compliance to the PS's mode byte DR = (CurrentPixel.R != 0) ? Int32Util.ClampToByte(src[x, y].R * 255 / CurrentPixel.R) : (byte)(0); byte DG = (CurrentPixel.G != 0) ? Int32Util.ClampToByte(src[x, y].G * 255 / CurrentPixel.G) : (byte)(0); byte DB = (CurrentPixel.B != 0) ? Int32Util.ClampToByte(src[x, y].B * 255 / CurrentPixel.B) : (byte)(0); CurrentPixel = ColorBgra.FromBgra(DB, DG, DR, CurrentPixel.A); break; Perhaps these codes are not perfect, and someone will be able to improve them. It would be very nice and helpful. P.S. Perhaps when the algorithms will be brought to perfection, Rick will include these additional modes into paint.net (although this is a great piece of work). Edited July 6, 2018 by toe_head2001 Fixed syntax highlighting 3 5 Quote Link to comment Share on other sites More sharing options...
TrevorOutlaw Posted February 6, 2018 Share Posted February 6, 2018 Thank you for this. I was able to create my own effect where I used Gaussian Blur, the default PDN blending options, and your algorithms through CodeLab. BlurBlend.zip 2 2 Quote Link to comment Share on other sites More sharing options...
Pratyush Posted February 7, 2018 Share Posted February 7, 2018 (edited) Does that mean the new Blend Modes are in work for PDN v4? Edited February 7, 2018 by Pratyush Quote Link to comment Share on other sites More sharing options...
kalodexD Posted February 7, 2018 Share Posted February 7, 2018 (edited) cool. Edited February 7, 2018 by kalodexD Quote Link to comment Share on other sites More sharing options...
ReMake Posted February 7, 2018 Author Share Posted February 7, 2018 2 hours ago, Pratyush said: Does that mean the new Blend Modes are in work for PDN v4? Yes, of couse. 2 Quote Link to comment Share on other sites More sharing options...
Pratyush Posted February 7, 2018 Share Posted February 7, 2018 @ReMake Thanks. Can't wait. 1 Quote Link to comment Share on other sites More sharing options...
ReMake Posted February 7, 2018 Author Share Posted February 7, 2018 7 minutes ago, Pratyush said: Can't wait. It depends on Rick only. Quote Link to comment Share on other sites More sharing options...
LionsDragon Posted February 7, 2018 Share Posted February 7, 2018 21 hours ago, TrevorOutlaw said: Thank you for this. I was able to create my own effect where I used Gaussian Blur, the default PDN blending options, and your algorithms through CodeLab. BlurBlend.zip Trevor, thank you for sharing! I gave this a test run last night and I'm quite impressed. 1 Quote Link to comment Share on other sites More sharing options...
TrevorOutlaw Posted February 11, 2018 Share Posted February 11, 2018 @ReMake I remember I was digging online and looking for the math behind the layer blending modes and found that Microsoft have their own versions as well. Is it worth taking a look? https://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx 1 Quote Link to comment Share on other sites More sharing options...
ReMake Posted February 11, 2018 Author Share Posted February 11, 2018 Thanks for information, @TrevorOutlaw. I will see it later. I think this information would be useful. 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.