|
| 1 | +packageMisc; |
| 2 | + |
| 3 | +importjava.awt.Color; |
| 4 | + |
| 5 | +/** |
| 6 | + * @brief A Java implementation of the offcial W3 documented procedure to calculate contrast ratio |
| 7 | + * between colors on the web. This is used to calculate the readability of a foreground color on |
| 8 | + * top of a background color. |
| 9 | + * @since 2020-10-15 |
| 10 | + * @see [Color Contrast Ratio](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure) |
| 11 | + * @author [Seth Falco](https://github.com/SethFalco) |
| 12 | + */ |
| 13 | +publicclassColorContrastRatio { |
| 14 | + |
| 15 | +/** |
| 16 | + * @brief Calculates the contrast ratio between two given colors. |
| 17 | + * @param a Any color, used to get the red, green, and blue values. |
| 18 | + * @param b Another color, which will be compared against the first color. |
| 19 | + * @return The contrast ratio between the two colors. |
| 20 | + */ |
| 21 | +publicdoublegetContrastRatio(Colora,Colorb) { |
| 22 | +finaldoubleaColorLuminance =getRelativeLuminance(a); |
| 23 | +finaldoublebColorLuminance =getRelativeLuminance(b); |
| 24 | + |
| 25 | +if (aColorLuminance >bColorLuminance) |
| 26 | +return (aColorLuminance +0.05) / (bColorLuminance +0.05); |
| 27 | + |
| 28 | +return (bColorLuminance +0.05) / (aColorLuminance +0.05); |
| 29 | + } |
| 30 | + |
| 31 | +/** |
| 32 | + * @brief Calculates the relative luminance of a given color. |
| 33 | + * @param color Any color, used to get the red, green, and blue values. |
| 34 | + * @return The relative luminance of the color. |
| 35 | + * @see [More info on relative |
| 36 | + * luminance.](https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef) |
| 37 | + */ |
| 38 | +publicdoublegetRelativeLuminance(Colorcolor) { |
| 39 | +finaldoublered =getColor(color.getRed()); |
| 40 | +finaldoublegreen =getColor(color.getGreen()); |
| 41 | +finaldoubleblue =getColor(color.getBlue()); |
| 42 | + |
| 43 | +return0.2126 *red +0.7152 *green +0.0722 *blue; |
| 44 | + } |
| 45 | + |
| 46 | +/** |
| 47 | + * @brief Calculates the final value for a color to be used in the relative luminance formula as |
| 48 | + * described in step 1. |
| 49 | + * @param color8Bit 8-bit representation of a color component value. |
| 50 | + * @return Value for the provided color component to be used in the relative luminance formula. |
| 51 | + */ |
| 52 | +publicdoublegetColor(intcolor8Bit) { |
| 53 | +finaldoublesRgb =getColorSRgb(color8Bit); |
| 54 | +return (sRgb <=0.03928) ?sRgb /12.92 :Math.pow((sRgb +0.055) /1.055,2.4); |
| 55 | + } |
| 56 | + |
| 57 | +/** |
| 58 | + * @brief Calculates the Color sRGB value as denoted in step 1 of the procedure document. |
| 59 | + * @param color8Bit 8-bit representation of a color component value. |
| 60 | + * @return A percentile value of the color component. |
| 61 | + */ |
| 62 | +privatedoublegetColorSRgb(doublecolor8Bit) { |
| 63 | +returncolor8Bit /255.0; |
| 64 | + } |
| 65 | + |
| 66 | +/** |
| 67 | + * You can check this example against another open-source implementation available on GitHub. |
| 68 | + * |
| 69 | + * @see [Online Contrast |
| 70 | + * Ratio](https://contrast-ratio.com/#rgb%28226%2C%20229%2C%20248-on-rgb%2823%2C%20103%2C%20154%29) |
| 71 | + * @see [GitHub Repository for Online Contrast Ratio](https://github.com/LeaVerou/contrast-ratio) |
| 72 | + */ |
| 73 | +privatestaticvoidtest() { |
| 74 | +finalColorContrastRatioalgImpl =newColorContrastRatio(); |
| 75 | + |
| 76 | +finalColorblack =Color.BLACK; |
| 77 | +finaldoubleblackLuminance =algImpl.getRelativeLuminance(black); |
| 78 | +assertblackLuminance ==0 :"Test 1 Failed - Incorrect relative luminance."; |
| 79 | + |
| 80 | +finalColorwhite =Color.WHITE; |
| 81 | +finaldoublewhiteLuminance =algImpl.getRelativeLuminance(white); |
| 82 | +assertwhiteLuminance ==1 :"Test 2 Failed - Incorrect relative luminance."; |
| 83 | + |
| 84 | +finaldoublehighestColorRatio =algImpl.getContrastRatio(black,white); |
| 85 | +asserthighestColorRatio ==21 :"Test 3 Failed - Incorrect contrast ratio."; |
| 86 | + |
| 87 | +finalColorforeground =newColor(23,103,154); |
| 88 | +finaldoubleforegroundLuminance =algImpl.getRelativeLuminance(foreground); |
| 89 | +assertforegroundLuminance ==0.12215748057375966 |
| 90 | + :"Test 4 Failed - Incorrect relative luminance."; |
| 91 | + |
| 92 | +finalColorbackground =newColor(226,229,248); |
| 93 | +finaldoublebackgroundLuminance =algImpl.getRelativeLuminance(background); |
| 94 | +assertbackgroundLuminance ==0.7898468477881603 |
| 95 | + :"Test 5 Failed - Incorrect relative luminance."; |
| 96 | + |
| 97 | +finaldoublecontrastRatio =algImpl.getContrastRatio(foreground,background); |
| 98 | +assertcontrastRatio ==4.878363954846178 :"Test 6 Failed - Incorrect contrast ratio."; |
| 99 | + } |
| 100 | + |
| 101 | +publicstaticvoidmain(Stringargs[]) { |
| 102 | +test(); |
| 103 | + } |
| 104 | +} |