[카테고리:] 미분류

  • jsQR 1.4.0

    jsQR 1.4.0(cdnjs 링크의 jsQR.min.js)

    원본 배포 코드 구조(비압축 dist/jsQR.js) 기준

    핵심 파이프라인(Top-level)

    jsQR(imageData, width, height, options?) → 아래 3단계로 진행됩니다. (GitHub)

    1. Binarize (그레이스케일→이진화)
    • RGBA를 밝기값으로 변환하고 임계값을 적용해 흑/백 모듈로 구성된 BitMatrix를 만듭니다.
    • 소스 구조상 dist/binarizer/ 타입정의와 최종 번들 안의 내부 함수로 구현됩니다. 목표는 “QR 모듈 대비를 가장 또렷하게” 만드는 것. (jsDelivr)
    1. Locate (QR 위치 찾기)
    • Finder 패턴(모서리의 ⬛⬜⬛ 링 구조)과 타이밍 패턴을 라인 스캔/런-렝스 기반으로 탐지해 세 꼭짓점과(필요 시) 정렬 패턴을 찾습니다.
    • 이후 투시변환을 위한 기하(코너/센터, 모듈 크기, 기울기)를 계산합니다. dist/locator/ 모듈로 분리되어 있으며 최종 번들에 합쳐집니다. (jsDelivr)
    1. Extract → Decode
    • 투시변환으로 원본 이미지에서 모듈 그리드를 샘플링(왜곡 보정).
    • 포맷/버전 정보(BCH) 복원 → 마스크 해제데이터 코드워드 추출 → 리드-솔로몬 오류정정 → 세그먼트 파싱(모드별: Numeric/Alphanumeric/Byte/ECI/Kanji)data 문자열과 binaryData 반환.
    • 디코더는 dist/decoder/(특히 reedsolomon, decodeData)에 구현. 반환객체에는 version, chunks, 그리고 location(corners & finder patterns) 포함. (jsDelivr)

    옵션과 API 포인트

    • 호출 방식: const code = jsQR(uint8ClampedRGBA, width, height, { inversionAttempts })
    • inversionAttempts: attemptBoth(기본), dontInvert, onlyInvert, invertFirst — 흑바탕/백모듈 QR도 탐지하려고 필요 시 이미지 반전 시도(성능엔 ~영향). (GitHub)
    • 반환 값: data, binaryData, chunks, version, location(코너/패턴 좌표). (GitHub)

    성능·정확도에 영향 주는 핵심 코드/아이디어

    • Adaptive한 임계값 & 반전 시도: 조명/노출 편차에 강인. 작은 QR이나 저대비 상황에서 binarize 품질이 성패를 가름. 최상위 옵션인 inversionAttempts가 이 경로를 제어. (GitHub)
    • Finder 패턴 런-렝스 검사: ⬛⬜⬛의 1:1:3:1:1 비율 근사치를 수평·수직으로 스캔해 후보를 모으고, 교차검증으로 오검출을 줄임(번들 내부 locator). (jsDelivr)
    • 투시변환 & 균일 샘플링: 검출한 코너로 호모그래피를 풀어 모듈 그리드를 일정 간격으로 샘플링. 왜곡/기울기/원근 보정의 품질이 곧 디코드 성공률. (UNPKG)
    • 리드-솔로몬: 오류/가림(occlusion) 복원. 코드워드 블록을 분리해 syndromes 계산→정정 후 데이터 재조립. (jsDelivr)
    • 문자셋 처리: 바이트 모드 + ECI/Shift-JIS 테이블로 멀티바이트 텍스트(일본어 Kanji 등) 파싱 지원. (jsDelivr)

    실제 적용 팁(현업 최적화)

    • 캔버스 세팅: CanvasRenderingContext2D 생성 시 willReadFrequently: truegetImageData 비용 완화. (브라우저 최적화 일반 팁)
    • 프레임 다운스케일: 카메라 원본이 크면 먼저 640~800px 근방으로 리사이즈 후 전달(모듈이 3~5px 이상 확보되도록).
    • 스캔 주기: requestAnimationFrame보다 **타이머 간격(예: 60–120ms)**로 CPU/GPU 점유 관리.
    • 반전 전략: 밝은 배경 어두운 QR만 들어온다면 inversionAttempts: 'dontInvert'~50% 가량 스캔 비용 절감. (GitHub)
    • 작은 QR 인식률: 카메라 포커스 고정/노출 고정 + 선명도 확보가 핵심(작은 QR 이슈 사례 다수). (Stack Overflow)

    코드 맵(배포 구조)

    • 단일 번들: dist/jsQR.js — 모든 서브모듈 포함. (UNPKG)
    • 세부분해(타입 정의 폴더):
      • binarizer/ — 이진화 관련 타입정의. (jsDelivr)
      • locator/ — 탐지(코너/패턴) 타입정의. (jsDelivr)
      • decoder/reedsolomon, decodeData 등 타입정의. (jsDelivr)

    최소 예제

    <video id="v" playsinline></video>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsqr/1.4.0/jsQR.min.js"></script>
    <script>
      // video → canvas → ImageData → jsQR
      const c = document.createElement('canvas'), ctx = c.getContext('2d', { willReadFrequently: true });
      async function tick() {
        const v = document.getElementById('v');
        c.width = v.videoWidth; c.height = v.videoHeight;
        ctx.drawImage(v, 0, 0, c.width, c.height);
        const { data, width, height } = ctx.getImageData(0, 0, c.width, c.height);
        const code = jsQR(data, width, height, { inversionAttempts: 'attemptBoth' });
        if (code) console.log(code.data, code.location);
        setTimeout(tick, 80);
      }
      // getUserMedia로 v 스트림 시작 후 tick();
    </script>
    

    필요하시면 **특정 함수 블록(예: 리드-솔로몬, 포맷정보 BCH, 투시변환 샘플러)**의 흐름을 실제 코드 라인 기준으로 더 디테일하게 주석 해설 버전으로 풀어드릴게요.

    — 참고

    • 공식 리드미(API/옵션/반환 구조). (GitHub)
    • 배포물 디렉터리(버전 1.4.0, 파일 구성). (jsDelivr)
    • 디코더 서브모듈(리드-솔로몬, 데이터 파서) 타입 정의. (jsDelivr)
    • 데모 페이지(웹캠 스캔 샘플). (cozmo.github.io)
    • 작은 QR 인식 이슈 사례(현업 팁 연동). (Stack Overflow)