처음에는 서버에서 이미지 배경 제거를 하는 방식으로 기획이 잡혀 있었습니다.
사용자가 서명이나 도장 이미지를 업로드하면, 서버에서 명암비를 조정해 배경을 없애고 선만 남겨주는 구조였죠.
하지만 실제로 테스트해보니 여러 문제가 있었습니다:
배경이 흰색이 아닐 경우(연회색, 아이보리 등) 제거가 잘 안 됨
배경이 흐리거나 노이즈가 있으면 서명 선까지 같이 사라짐
서버에 매번 이미지를 보내야 해서 UX도 좋지 않음
즉, 실제 사용자 이미지들을 안정적으로 처리하기 어렵고 느린 방식이었습니다.
저는 프론트엔드 개발자로서, 이 문제를 서버가 아닌 프론트 단에서 Canvas API로 직접 처리할 수 있다는 점을 발견했습니다.
Canvas API를 사용하면:
이미지를 픽셀 단위로 읽고
배경과 전경을 직접 분리하고
클라이언트에서 즉시 결과를 확인할 수 있습니다.
그래서 서버에서 처리하던 기존 방식을 대신해, 프론트 단에서 전처리하는 방향으로 전환하자고 제안했고, 실제로 이 접근으로 문제를 해결했습니다.
let totalR = 0, totalG = 0, totalB = 0, count = 0;
for (let i = 0; i < data.length; i += 4) {
if (data[i + 3] > 250) { // 불투명 픽셀만
totalR += data[i];
totalG += data[i + 1];
totalB += data[i + 2];
count++;
}
}
const avgR = totalR / count;
const avgG = totalG / count;
const avgB = totalB / count;
→ 이미지 전체의 평균 색상을 구해서 배경색 후보로 사용합니다.
즉, 반드시 흰색이 아니어도, 밝은 계열 배경이면 처리할 수 있습니다.
const contrast = Math.abs(avgR - r) * 0.299
+ Math.abs(avgG - g) * 0.587
+ Math.abs(avgB - b) * 0.114;
if (contrast > 50) {
// 전경(서명/도장)
data[i] = 0; data[i+1] = 0; data[i+2] = 0; data[i+3] = 255;
} else {
// 배경은 투명 처리
data[i+3] = 0;
}
→ 배경과 충분히 대비(contrast)가 나는 픽셀만 남기고, 나머지는 투명화합니다.
이 덕분에 단순히 흰 배경 + 검정 서명뿐 아니라,
밝은 배경 + 어두운 서명
빨간 도장
흐린 스캔본
등 일반적인 상황 전반을 처리할 수 있었습니다.
if (options.mode === 'contrast') {
// 검정 서명용
} else if (options.mode === 'redLine') {
// 빨간 도장용
}
→ 옵션을 나눠서 검정 서명과 빨간 도장을 각각 처리할 수 있게 했습니다.
서버 기반 처리의 한계를 클라이언트 전처리로 해결
픽셀 단위 명암비 계산으로 다양한 배경 색상에서도 안정적으로 서명/도장을 추출 가능
흰색 배경 + 검정 서명뿐 아니라, 밝은 배경 + 어두운 서명, 빨간 도장에도 적용 가능
서버 왕복 없이 클라이언트에서 즉시 결과 확인 → UX 개선