pascal Posted June 7, 2020 Share Posted June 7, 2020 (edited) [June 28th 2022] Version 5 available! This plugin can be used to simulate certain colorblindness types such as: protanopia, deuteranopia, tritanopia, achromatopsia and blue-cone monochromacy. Download: colorblindness.zip Can be found in Effects > Color > Colorblindness Note: if you have an older version installed, remove it manually from the Paint.NET Effects folder. The old version is called colorblindness4.dll. The new version does not include the version number in the name. Preview: Code: Spoiler #region UICode ListBoxControl<Deficiency> type = Deficiency.Default; //Color blindness type|Protanopia|Deuteranopia|Tritanopia|Achromatopsia|Blue-Cone Monochromacy|Normal Vision #endregion enum Deficiency { [LmsMatrix( 0, 1.05118294, -0.05116099, 0, 1, 0, 0, 0, 1)] Protanopia, [LmsMatrix( 1, 0, 0, 0.9513092, 0, 0.04866992, 0, 0, 1)] Deuteranopia, [LmsMatrix( 1, 0, 0, 0, 1, 0, -0.86744736, 1.86727089, 0)] Tritanopia, [LmsMatrix( 0.4, 0.6, 0, 0.4, 0.6, 0, 0.4, 0.6, 0)] Achromatopsia, [LmsMatrix( 0, 0, 1, 0, 0, 1, 0, 0, 1 )] Blue_Cone_Monochromacy, [LmsMatrix( 1, 0, 0, 0, 1, 0, 0, 0, 1)] Default } static double[,] toLmsMatrix = toMatrix(3, 3, 0.31399022, 0.63951294, 0.04649755, 0.15537241, 0.75789446, 0.08670142, 0.01775239, 0.10944209, 0.87256922); static double[,] toLinearRgbMatrix = toMatrix(3, 3, 5.47221206, -4.6419601, 0.16963708, -1.1252419, 2.29317094, -0.1678952, 0.02980165, -0.19318073, 1.16364789); class LmsMatrix: Attribute { public double[,] matrix {get; private set;} internal LmsMatrix(params double[] matrix) { this.matrix = toMatrix(3, 3, matrix); } public static LmsMatrix getMatrix(Deficiency d) { return (LmsMatrix) Attribute.GetCustomAttribute(deficiencyOf(d), typeof(LmsMatrix)); } static MemberInfo deficiencyOf(Deficiency d) { return typeof(Deficiency).GetField(Enum.GetName(typeof(Deficiency), d)); } } static double[,] toLinear(params byte[] rgb) { double[,] linear = new double[rgb.Length, 1]; for (int i = 0; i < linear.Length; i++) { linear[i, 0] = Math.Clamp(rgb[i] <= 0.04045 * 255.0 ? (rgb[i] / 255.0) / 12.92 : Math.Pow((rgb[i] / 255.0 + 0.055) / 1.055, 2.4), 0.0, 1.0); } return linear; } static byte[] fromLinear(double[,] linear) { byte[] normal = new byte[linear.GetLength(0)]; for (int i = 0; i < normal.Length; i++) { double l = Math.Clamp(linear[i, 0], 0.0, 1.0); normal[i] = Math.Clamp((byte) (l <= 0.0031308 ? l * 255.0 * 12.92 : 255.0 * (1.055 * Math.Pow(l, 0.41666) - 0.055)), (byte) 0, (byte) 255); } return normal; } static double[,] multiplyMatrix(double[,] a, double[,] b) { int rA = a.GetLength(0); int cA = a.GetLength(1); int cB = b.GetLength(1); double[,] result = new double[rA, cB]; for (int i = 0; i < rA; i++) { for (int j = 0; j < cB; j++) { double temp = 0; for (int k = 0; k < cA; k++) { temp += a[i, k] * b[k, j]; } result[i, j] = temp; } } return result; } static double[,] toMatrix(int rows, int columns, params double[] values) { double[,] result = new double[rows, columns]; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { result[i, j] = values[j + i * columns]; } } return result; } static double[,] getColorBlindnessMatrix(double[,] lmsMatrix) { return multiplyMatrix( multiplyMatrix( toLinearRgbMatrix, lmsMatrix), toLmsMatrix ); } static ColorBgra applyColorBlindnessMatrix(double[,] matrix, ColorBgra pixel) { byte[] rgb = new byte[]{pixel.R, pixel.G, pixel.B}; byte[] newRgb = fromLinear( multiplyMatrix( matrix, toLinear(rgb) ) ); return ColorBgra.FromBgra(newRgb[2], newRgb[1], newRgb[0], pixel.A); } void Render(Surface dst, Surface src, Rectangle rect) { double[,] matrix = getColorBlindnessMatrix(LmsMatrix.getMatrix(type).matrix); for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; for (int x = rect.Left; x < rect.Right; x++) { dst[x,y] = applyColorBlindnessMatrix(matrix, src[x,y]); } } } Edited June 28, 2022 by pascal Removed redundant code 2 4 Quote Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted June 8, 2020 Share Posted June 8, 2020 Hi Pascal & welcome to the forum Good job on this plugin. There is this older plugin - but it doesn't do the tritanopia effect....https://forums.getpaint.net/topic/19780-colourblind-simulation/ If you want help cleaning up your code post it over here: https://forums.getpaint.net/forum/17-plugin-developers-central/ 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...
Seerose Posted July 2, 2020 Share Posted July 2, 2020 ❤️ @pascal! Welcome, and thank you very much for your effort. Quote Live as if you were to die tomorrow. Learn as if you were to live forever. Gandhi Link to comment Share on other sites More sharing options...
mumu64 Posted July 13, 2020 Share Posted July 13, 2020 Nice, thanks for making and sharing. Quote Link to comment Share on other sites More sharing options...
Djisves Posted October 9, 2020 Share Posted October 9, 2020 (edited) On 6/7/2020 at 9:44 PM, pascal said: New version available! Thank you @pascal for the new version. This post will let everyone know there's been a change, so that they download the new version. You should really make a new post when you update the plugin, otherwise users will have no way of knowing. I was only alerted to this because of your posts on the General Discussion forum. Also, it's better not to use the plugin version number in the name of the DLL file itself. If the file name of the newer version is not identical to the previous version, it will not replace the older one in the Effects folder. This will result with two (or more) copies of your plugin in the Effects folder and whatever problems that may cause. Naming the containing zip file with the version number is OK, even helpful. I like it and wish plugin authors would adopt it as a standard. Edited October 9, 2020 by Djisves version number Quote Link to comment Share on other sites More sharing options...
pascal Posted June 28, 2022 Author Share Posted June 28, 2022 Version 5 available - The new version is more accurate than before. It converts the RGB values to the LMS color space and takes gamma correction into account. - Protanomaly, deuteranomaly, tritanomaly and achromatomaly are removed from the plugin because those were just blending between normal vision and the corresponding deficiency. - The deficiency 'Blue-Cone Monochromacy' was added as a second type of monochromacy. 2 1 Quote Link to comment Share on other sites More sharing options...
clean_beans Posted December 14, 2022 Share Posted December 14, 2022 Registered just to say thank you very much for creating and maintaining this plugin. It really helps with designing maps that everyone can use when I teach history courses. 1 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.