05/05/2022

Target

Make an Chrome extension to help people with colour deficiency viewing webpages.

Motivation

1 in 12 men are colour blind.
1 in 200 women are colour blind.
The internet has become the most common and effective way of acquiring knowledge.

Categories of colour blindness

  • Red-green
    • Protanopia (red-blind)
    • Protanomaly (red-weak)
    • Deuteranopia (green-blind)
    • Deuteranomaly (green-weak)
  • Blue-yellow
    • Tritanopia (blue-blind)
    • Tritanomaly (blue-weak)
  • Completely lacking of colour
    • Monochromacy

What is RGB (Additive Colour vs Subtractive Colour)

Solution

Modify the RGB colour value to increase contrast between text and background to make text easier to read.

Result

Before

Result

After

Pipeline

  1. Retrieve elements in the page
  2. Sense change in value in pop up page
  3. Change the colour of element according to the desire change in contrast

Retrive elements

JavaScript

Retrive elements

Code

elements = document.getElementsByTagName("*");

Retrive elements

Create elements as examples

var p1 = document.createElement("p");
var p2 = document.createElement("p");
var div1 = document.createElement("div");
p1.style.backgroundColor = "#646464";
p1.style.color = "rgb(100,80,120)";
p1.innerHTML = "P1";
p2.style.backgroundColor = "rgba(180,200,220,0.5)";
p2.style.color = "rgb(190,200,220)";
div1.style.backgroundColor = "rgb(10,10,10)";
div1.style.color = "rgb(5,5,5)";

Retrive elements

Colour Format

window.getComputedStyle(p1).getPropertyValue("background-color")
window.getComputedStyle(p1).getPropertyValue("color")
window.getComputedStyle(p2).getPropertyValue("background-color")
window.getComputedStyle(p2).getPropertyValue("color")
window.getComputedStyle(div1).getPropertyValue("background-color")
window.getComputedStyle(div1).getPropertyValue("color")






Retrive elements

Change element colour string to numbers

var color = p2.style.backgroundColor;
var colNums = color.split("(")[1];
colNums = colNums.substring(0, colNums.length -1);
colNums = colNums.split(",");
colNums




Sense input from pop up page

Sense input from pop up page

Code pop up page script

slider.oninput = function() {
        //Start a message port
        chrome.tabs.query({currentWindow: true, active: true}, function (tabs){
            var activeTab = tabs[0];
            
            //Send message on the value of the silder
            chrome.tabs.sendMessage(activeTab.id, {"contrast": `${slider.value/100}`});
        });
    }

Sense input from pop up page

Code content script

#Add listener to listen messages from popup menu
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.message = "message"){
        func1();
    };
    else if (Number(request.message) !== NaN){
        func2();
    }
);

Increase Contrast of the Colours

Increase Contrast of the Colours

Colour to Contrast Formula (repeat with red, blue, green and get R, G, B)

\[ R_{sRGB}=R_{8\mathrm{bit}}\div255 \] \[ \mathrm{if\ }R_{sRGB}\le0.03928\mathrm{\ then\ }R=\frac{R_{sRGB}}{12.92}\mathrm{,\ else\ }R=\left(\frac{R_{sRGB}+0.055}{1.055}\right)^{2.4} \] \[ \mathrm{luminance}=0.2126\cdot R+0.7152\cdot G+0.0722\cdot B \] \[ \mathrm{contrast}=\frac{\mathrm{luminance\ 1}+0.5}{\mathrm{luminance\ 2}+0.5} \] Luminance 1 > Luminance 2

R vs R_sRGB (very low value)

g <- ggplot(data = data.frame(x = 0), mapping = aes(x = x))
fun2 <- function(x) x/12.92
fun3 <- function(x) ((x + 0.055)/1.055)^2.4
g2 <- g + stat_function(fun = fun2, aes(color = "formula 1")) +
    xlim(0, 0.03928) + stat_function(fun = fun3, aes(color = "formula2")) +
    labs(x = "R_sRGB", y = "R", title = "R vs R_sRGB")
print(g2)

R vs R_sRGB (most values)

fun1 <- function(x) ifelse(x <= 0.03928, fun2(x), fun3(x))
g1 <- g + stat_function(fun = fun1) + xlim(0, 1) +
    labs(x = "R_sRGB", y = "R", title = "R vs R_sRGB")
print(g1)

Increase Contrast of the Colours

Original colour + Degree (Contrast Change) to new colour

The colour with higher luminance will change its luminance by \(((\mathrm{lum1} + 0.05)\cdot\sqrt{\mathrm{contrast ~ change}} - 0.05)\div\mathrm{lum1}\)
The colour with lower luminance will change its luminance by \(((\mathrm{lum2}+0.05)\cdot\frac1{\sqrt{\mathrm{contrast ~ change}}}-0.05)\div\mathrm{lum2}\)

Increase Contrast of the Colours

Original colour + Degree (Contrast Change) to new colour

\[ d=\mathrm{degree},r_o=\mathrm{original~colour~value},r_n=\mathrm{new~color~value} \] \[ r_n=r_o\cdot d^{\frac1{2.4}}+0.055\cdot255\cdot(d^{\frac1{2.4}}-1) \] \[ \mathrm{if~}r_n\le0.03928,~r_n=r_o\cdot d \]

Increase Contrast of the Colours

Python

#Algorithm for increasing luminance of color, assuming R always = (r+0.055)/1.055) ** 2.4
#input: 100, output: 166.1940116887105
import math
def reverseColor(value,degree):
    value = int(value)
    degree = float(degree)
    result = value*math.pow(degree,1/2.4) - 255 * 0.055 * (1- math.pow(degree,1/2.4))
    return result

def changeluminance(r,g,b,degree):
    tempR = reverseColor(r,degree)
    tempG = reverseColor(g,degree)
    tempB = reverseColor(b,degree)
    return (tempR, tempG, tempB)

Code

Python

print(apply(changeluminance(100,100,100,1.5),"round", ndigits=1))
## [121.0, 121.0, 121.0]
print(apply(changeluminance(80,100,120,1.5),"round", ndigits=1))
## [97.3, 121.0, 144.7]
print(apply(changeluminance(100,100,100,0.5),"round", ndigits=1))
## [71.4, 71.4, 71.4]

Code

JavaScript

var col1 = [110,120,130]; var col2 = [100,110,120];
console.log(rgbLum(col1[0], col1[1], col1[2]),rgbLum(col2[0], col2[1], col2[2]));
console.log(rgbToCon(col1,col2));
var [nCol1,nCol2] = increaseContrast(col1,col2,degree = 7);
console.log(rgbLum(nCol1[0], nCol1[1], nCol1[2]),rgbLum(nCol2[0], nCol2[1], nCol2[2]));
console.log(rgbToCon(nCol1,nCol2));
console.log(rgbToCon(nCol1,nCol2)/rgbToCon(col1,col2))
## 0.18359644105200248 0.15217251746456573
## 1.1554312326003675
## 0.5680380901733579 0.026414029020443368
## 8.088018628202574
## 7.000000000000002

Result

Before:
After:

Process

Flow chart

Evaluation

Limitations

  • The extension’s colour change will be based on the colour when the page is loaded. The extension cannot change the colour if the element is created and added to the webpage after the page is fully loaded.
  • The extension cannot change the colour of background if it is transparent or it is a image.
  • The extension have bugs if you try to reduce the contrast.

Research

  • Different Type of Colour Blindness
  • The webpage guideline
  • The method of calculating Contrast and Luminance
  • How to build a Chrome Extension

Skill Developed

  • Documentation Technique
  • JavaScript
  • Note taking methods

How this project help me

  • It build my experience of doing a formal project, helping me on my future projects
  • Let me build my own noting taking style.

Q&A