Skip to content

Implement Color Contrast Ratio + Unit Tests #2023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/main/java/com/others/ColorContrastRatio.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.others;

import java.awt.Color;

/**
* A Java implementation of the official W3 documented procedure
* to calculate contrast ratio between colors on the web.
*
* This is used to calculate the readability of a foreground color
* on top of a background color.
*
* @since 2020-10-15
* @see <a href="https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure">Color Contrast Ratio Procedure</a>
*/
public class ColorContrastRatio {

/**
* Calculates the contrast ratio between two given colors.
*
* @param a Any color, used to get the red, green, and blue values.
* @param b Another color, which will be compared against the first color.
* @return The contrast ratio between the two colors.
*/
public double getContrastRatio(Color a, Color b) {
final double aColorLuminance = getRelativeLuminance(a);
final double bColorLuminance = getRelativeLuminance(b);

if (aColorLuminance > bColorLuminance)
return (aColorLuminance + 0.05) / (bColorLuminance + 0.05);
else
return (bColorLuminance + 0.05) / (aColorLuminance + 0.05);
}

/**
* Calculates the relative luminance of a given color.
*
* @param color Any color, used to get the red, green, and blue values.
* @return The relative luminance of the color.
* @see <a href="https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef">More info on relative luminance.</a>
*/
public double getRelativeLuminance(Color color) {
final double red = getColor(color.getRed());
final double green = getColor(color.getGreen());
final double blue = getColor(color.getBlue());

return 0.2126 * red + 0.7152 * green + 0.0722 * blue;
}

/**
* Calculates the final value for a color to be used in the
* relative luminance formula as described in step 1.
*
* @param value The 8-bit representation of a color component value.
* @return Value for the provided color component to be used in the relative luminance formula.
*/
public double getColor(int value) {
final double sRgb = getColorSRgb(value);
return (sRgb <= 0.03928) ? sRgb / 12.92 : Math.pow((sRgb + 0.055) / 1.055, 2.4);
}

/**
* Calculates the Color sRGB value as denoted in step 1
* of the procedure document.
*
* @param color8Bit The 8-bit representation of a color component value.
* @return A percentile value of the color component.
*/
private double getColorSRgb(double color8Bit) {
return color8Bit / 255.0;
}
}
56 changes: 56 additions & 0 deletions src/test/java/com/others/ColorContrastRatioTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.others;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.awt.Color;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* You can check the examples against another open-source implementation available on GitHub.
*
* @see <a href="https://contrast-ratio.com/#rgb%28226%2C%20229%2C%20248-on-rgb%2823%2C%20103%2C%20154%29">Online Contrast Ratio</a>
* @see <a href="https://github.com/LeaVerou/contrast-ratio">GitHub Repository for Online Contrast Ratio</a>
*/
public class ColorContrastRatioTest {

private static ColorContrastRatio ccr;

@BeforeAll
public static void before() {
ccr = new ColorContrastRatio();
}

@Test
public void testRelativeLuminance() {
final double expected = 0.12215748057375966;
final double actual = ccr.getRelativeLuminance(new Color(23, 103, 154));

assertEquals(expected, actual);
}

@Test
public void testRelativeLuminance2() {
final double expected = 0.7898468477881603;
final double actual = ccr.getRelativeLuminance(new Color(226, 229, 248));

assertEquals(expected, actual);
}

@Test
public void testColorContrastRatio() {
final double expected = 4.878363954846178;
final double actual = ccr.getContrastRatio(new Color(23, 103, 154), new Color(226, 229, 248));

assertEquals(expected, actual);
}

@Test
public void testColorContrastRatioInverse() {
final double expected = 4.878363954846178;
final double actual = ccr.getContrastRatio(new Color(226, 229, 248), new Color(23, 103, 154));

assertEquals(expected, actual);
}
}