대비 검사기 설명 및 코딩

Apr 26 2023
나쁜 대비는 웹 페이지에서 두 색상 간의 밝기 차이가 너무 낮아 일부 사용자, 특히 시각 장애가 있는 사용자가 색상을 구분하기 어려울 때 발생합니다. 디자이너와 개발자가 접근성 표준을 준수할 수 있도록 W3C(World Wide Web Consortium)에서 게시한 WCAG(웹 콘텐츠 접근성 지침)는 AA 및 AAA의 두 가지 준수 수준을 지정합니다.
이 사진을 보니 눈이 아프네요

나쁜 대비는 웹 페이지에서 두 색상 간의 밝기 차이가 너무 낮아 일부 사용자, 특히 시각 장애가 있는 사용자가 색상을 구분하기 어려울 때 발생합니다. 디자이너와 개발자가 접근성 표준을 준수할 수 있도록 W3C(World Wide Web Consortium)에서 게시한 WCAG(웹 콘텐츠 접근성 지침)는 AA 및 AAA의 두 가지 준수 수준을 지정합니다. AA 규정을 준수하려면 일반 텍스트의 경우 최소 4.5:1, 큰 텍스트의 경우 3:1의 명암비가 필요합니다. AAA 규정을 준수하려면 일반 텍스트의 경우 최소 7:1, 큰 텍스트의 경우 4.5:1의 명암비가 필요합니다.

명암비를 계산하기 위해 명암 검사기는 일반적으로 (L1 + 0.05) / (L2 + 0.05) 공식을 사용합니다. 여기서 L1과 L2는 비교할 두 색상의 휘도 값입니다. 각 광도 값에 0.05를 추가하면 0으로 나누기 오류를 방지하고 명암비가 항상 1과 21 사이가 되도록 하는 작은 조정입니다.

이론을 실제로 적용하여 사용자가 제출한 이미지의 대비를 평가하는 이 간단한 대비 검사기를 개발했습니다.

const fileInputElement = document.getElementById('fileInput');
const imageElement = document.getElementById('image');
const resultElement = document.getElementById('result');


fileInputElement.addEventListener('change', () => {

  const file = fileInputElement.files[0];
  const reader = new FileReader();
  reader.readAsDataURL(file);

  reader.onload = () => {
    imageElement.src = reader.result;
    imageElement.onload = () => {
      const contrastRatio = calculateContrastRatio(imageElement);
      displayResult(contrastRatio);
    }
  }
});


function calculateContrastRatio(image) {

  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  canvas.width = image.width;
  canvas.height = image.height;


  context.drawImage(image, 0, 0);
  const imageData = context.getImageData(0, 0, image.width, image.height);
  const pixels = imageData.data;


  let lightestColor = 0;
  let darkestColor = 255;


  for (let i = 0; i < pixels.length; i += 4) {
    const red = pixels[i];
    const green = pixels[i + 1];
    const blue = pixels[i + 2];
    const alpha = pixels[i + 3] / 255;
    const luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue;


    lightestColor = Math.max(luminance, lightestColor);
    darkestColor = Math.min(luminance, darkestColor);
  }

  const contrastRatio = (lightestColor + 0.05) / (darkestColor + 0.05);
  return contrastRatio.toFixed(2);
}

function displayResult(contrastRatio) {
  let color;
  let message;

  if (contrastRatio >= 4.5) {
    color = 'green';
    message = `Contrast Ratio: ${contrastRatio}:1 (Passes WCAG 2.0 AA)`;
  } else if (contrastRatio >= 3) {
    color = 'orange';
    message = `Contrast Ratio: ${contrastRatio}:1 (Passes WCAG 2.0 AA for large text)`;
  } else {
    color = 'red';
    message = `Contrast Ratio: ${contrastRatio}:1 (Fails WCAG 2.0 AA)`;
  }


  resultElement.style.color = color;
  resultElement.textContent = message;
}

calculateContrastRatio함수는 이미지를 인수로 사용하여 캔버스와 컨텍스트를 만들고 이미지와 일치하도록 캔버스 너비와 높이를 설정합니다. 그런 다음 캔버스에 이미지를 그리고 컨텍스트에서 이미지 데이터 개체를 검색합니다. 이미지 데이터의 픽셀을 반복하면서 각 픽셀의 휘도를 계산하고 가장 밝은 색상과 가장 어두운 색상을 추적합니다. 마지막으로 두 색상 간의 명암비를 계산하여 반환합니다.

displayResult함수는 명암비를 인수로 사용하고 비율 값에 따라 지정된 요소의 색상 및 텍스트 콘텐츠를 설정합니다. 비율이 4.5 이상이면 WCAG 2.0 AA 접근성 지침을 통과한 것으로 간주되며 메시지가 녹색으로 표시됩니다. 비율이 3보다 크거나 같으면 큰 텍스트를 통과하는 것으로 간주되며 주황색으로 표시됩니다. 비율이 3 미만이면 실패하고 빨간색으로 표시됩니다.

물론 이 코드는 다른 접근성 관련 요구 사항을 충족하도록 개선 및 확장될 수 있습니다. 전체 코드를 확인하십시오.