1 module magicalrainbows.properties; 2 3 import magicalrainbows.utils; 4 5 Precision relativeLuminosity(Precision = double, Colour)(const Colour colour) if(isColourFormat!Colour) { 6 const linear = colour.asLinearRGB!Precision; 7 return 0.2126 * linear.red + 8 0.7152 * linear.green + 9 0.0722 * linear.blue; 10 } 11 /// 12 @safe pure unittest { 13 import magicalrainbows.formats : BGR555, RGB888; 14 import std.math : isClose; 15 assert(RGB888(0, 0, 0).relativeLuminosity.isClose(0.0)); 16 assert(RGB888(255, 255, 255).relativeLuminosity.isClose(1.0)); 17 assert(RGB888(250, 112, 20).relativeLuminosity.isClose(0.3196284130)); 18 assert(BGR555(0, 16, 31).relativeLuminosity.isClose(0.2361773154)); 19 } 20 21 Precision contrast(Precision = double, Colour1, Colour2)(const Colour1 colour1, const Colour2 colour2) if (isColourFormat!Colour1 && isColourFormat!Colour2) { 22 import std.algorithm.comparison : max, min; 23 const L1 = colour1.relativeLuminosity!Precision; 24 const L2 = colour2.relativeLuminosity!Precision; 25 return (max(L1, L2) + 0.05) / (min(L1, L2) + 0.05); 26 } 27 /// 28 @safe pure unittest { 29 import magicalrainbows.formats : RGB888; 30 import std.math : isClose; 31 assert(contrast(RGB888(0, 0, 0), RGB888(0, 0, 0)).isClose(1.0)); 32 assert(contrast(RGB888(0, 0, 0), RGB888(255, 255, 255)).isClose(21.0)); 33 assert(contrast(RGB888(255, 255, 255), RGB888(0, 0, 0)).isClose(21.0)); 34 assert(contrast(RGB888(255, 255, 255), RGB888(250, 112, 20)).isClose(2.8406907130)); 35 } 36 37 Colour complementary(Colour)(const Colour colour) if (isColourFormat!Colour) { 38 Colour result; 39 static if (hasRed!Colour) { 40 result.red = colour.red^maxRed!Colour; 41 } 42 static if (hasGreen!Colour) { 43 result.green = colour.green^maxGreen!Colour; 44 } 45 static if (hasBlue!Colour) { 46 result.blue = colour.blue^maxBlue!Colour; 47 } 48 return result; 49 } 50 /// 51 @safe pure unittest { 52 import magicalrainbows.formats : RGB888; 53 assert(RGB888(0, 0, 0).complementary == RGB888(255, 255, 255)); 54 assert(RGB888(255, 255, 255).complementary == RGB888(0, 0, 0)); 55 assert(RGB888(0, 255, 255).complementary == RGB888(255, 0, 0)); 56 assert(RGB888(0, 128, 0).complementary == RGB888(255, 127, 255)); 57 }