디더링 QR 코드: 사진이 스캔 가능한 코드가 되는 원리
대부분의 "예술적" QR 코드는 그림 위에 코드를 찍어 놓은 것입니다. 디더링 QR 코드는 다른 것입니다. 이미지는 하나뿐이며 코드는 그 입자의 일부입니다. 이 글은 코드가 실제로 필요로 하는 것, 오차 확산 디더링의 작동 방식, 둘이 하나의 사각형을 공유하게 하는 한 가지 변경, 결과를 결정하는 두 가지 설정, 그리고 실패하는 세 가지 방식을 설명합니다.
QR 코드가 실제로 필요로 하는 것에서 시작하기
QR 코드는 모듈, 즉 어둡거나 밝은 작은 사각형들의 격자입니다. 그중 일부는 구조적이어서 옮길 수 없습니다. 스캐너가 코드를 찾고 방향을 잡게 해 주는 모서리의 큰 사각형 세 개, 그 사이의 가늘게 교차하는 선, 작은 정렬 사각형, 그리고 형식과 버전을 인코딩하는 띠입니다. 나머지는 모두 데이터와 오류 정정 바이트입니다. 그 오류 정정이 틈새입니다. 최고 단계에서는 코드의 약 30%가 파괴되어도 리더가 여전히 페이로드를 복구합니다. 그러니 코드가 완벽할 필요는 없습니다. 중요한 곳에서 완벽하고 나머지에서는 충분히 가까우면 됩니다. 이 구분을 기억해 두십시오. 기법 전체가 여기에 기대고 있습니다. 구조 모듈은 건드릴 수 없는 것으로 다루고, 데이터 영역은 카메라가 보는 규모에서 평균적으로만 맞으면 되는 것으로 다룹니다. 그림을 코드에 넣는 모든 생성기는 그 30% 예산의 일부를 씁니다. 문제는 얼마나 신중하게 쓰느냐, 그리고 그 대가가 눈에 보이느냐뿐입니다.
디더링을 한 문단으로
Floyd–Steinberg 디더링은 회색조 사진을 순수한 흑백으로 바꿉니다. 픽셀을 순서대로 훑습니다. 각 픽셀에서 검정과 흰색 중 가까운 쪽을 고른 뒤, 방금 만든 오차, 즉 원했던 회색과 출력한 값의 차이를 아직 방문하지 않은 이웃에게 밀어냅니다. 가중치는 오른쪽 픽셀에 7/16, 아래 세 픽셀에 3/16, 5/16, 1/16입니다. 각 이웃은 자기 차례가 왔을 때 약간 조정된 값에서 시작하므로 오차는 결코 사라지지 않고 옮겨질 뿐입니다. 그림은 국소 밀도가 원래 밝기에 대응하는 얼룩의 장으로 나옵니다. 중간 회색 영역은 대략 절반이 검은 점이 되고, 하이라이트는 흰 바탕의 드문 점이 되며, 그림자는 검은 바탕의 드문 흰 점이 됩니다. 멀리서 보면 눈이 얼룩을 다시 계조로 평균하므로, 모든 픽셀이 두 색 중 하나뿐이어도 디더링된 이미지는 사진으로 읽힙니다. 그 평균화는 카메라가 작은 인쇄물을 볼 때 하는 것과 같으며, 이 기법이 이용하는 것이 바로 그것입니다.
비결
코드를 모듈당 고정 픽셀 수로 렌더링합니다. SWAPQR은 9를 쓰므로 모든 모듈은 9×9 블록입니다. 그런 다음 사각형 전체에 걸쳐 사진을 디더링하되 한 가지를 바꿉니다. 코드가 특정 값을 요구하는 곳에서는 임계값 처리를 하지 않습니다. 픽셀을 코드가 필요로 하는 값으로 강제하고, 그 강제가 만든 오차를 측정하고, 다른 오차와 정확히 똑같이 확산시킵니다. 이 마지막 구절이 발상의 전부입니다. 강제된 점은 그림 위에 칠해지는 것이 아니라 주변 픽셀이 대가를 치르며, 주변 픽셀은 보상하기 위해 이동합니다. 강제된 점은 다른 모든 것과 같은 후추소금 질감 안에 자리 잡으므로 눈에는 이를 구별할 근거가 없습니다. 구조 모듈, 즉 파인더, 타이밍, 정렬, 형식은 단색으로 그리고 건드리지 않습니다. 오류 정정이 도움이 되기 전에 스캐너가 코드를 찾아야 하기 때문입니다. 여기서 설명한 기법은 2026년에 디더링 QR 생성에 관해 글을 쓴 Andrew T.가 발표한 접근법을 따릅니다. SWAPQR의 구현은 그의 소스를 이식한 것이 아니라 그 설명을 바탕으로 작성되었습니다.
모든 것을 결정하는 두 개의 손잡이
첫째는 각 모듈의 얼마만큼을 강제하느냐입니다. 중앙 픽셀만 강제하면 그림은 거의 손상되지 않지만 코드는 취약합니다. 모듈당 픽셀 하나가 프린터와 카메라 센서 사이의 모든 리샘플링 단계를 살아남아야 합니다. 9×9 중 7×7 블록을 강제하면 코드는 견고해지고 그림은 희미해집니다. 이제 모든 모듈의 대부분이 단색이기 때문입니다. SWAPQR은 이를 사진 ↔ 코드 균형으로 직접 노출하며 사진, 중간, 코드 위치가 있어서, 이 절충은 생성기에 숨겨진 상수가 아니라 여러분이 내리는 선택이 됩니다. 둘째는 각 모듈을 얼마나 밀어 주느냐입니다. 디더링 전에 어두운 모듈의 모든 픽셀을 조금 어둡게 하고 밝은 모듈의 모든 픽셀을 조금 밝게 합니다. 그림은 세부를 유지하지만 모듈의 평균 계조는 올바른 방향으로 기웁니다. 이것이 카메라가 방 건너편에서 작은 인쇄 코드를 볼 때 보는 것입니다. 두 설정이 함께 결과가 희미한 코드가 든 사진이 될지 희미한 사진이 든 코드가 될지를 결정하며, 특정 인쇄물이 그 선 위 어디에 놓여야 하는지는 어떻게 스캔될지에 달려 있습니다.
실패하는 지점, 그리고 그럴 가치가 있는가
실패 방식은 세 가지이며, 모두 실재하고, 어느 것도 수수께끼가 아닙니다. 평평한 사진: 고르게 조명된 단일 계조 이미지는 규칙적인 체커보드로 디더링되는데, 이것이 바로 코드와 경쟁하는 질감이므로 사진에는 진짜 명암 범위가 필요하고 스튜디오는 그것이 없을 때 경고합니다. 긴 링크: 글자가 많을수록 같은 사각형에 모듈이 많아지므로 각 모듈이 가지는 그림이 줄어듭니다. 대략 버전 8, 즉 49×49 모듈을 넘으면 사진이 있을 자리가 없으며, 짧은 리디렉션 링크가 해결책입니다. 그리고 일부 리더에서의 극단적인 근접 스캔인데, 이는 직관에 반하는 만큼 이 가이드에 별도의 글이 있습니다. 예술적 코드는 항상 신뢰성과의 절충입니다. 코드가 디자인의 일부이고 누군가 의도적으로 스캔할 곳, 즉 포스터, 앨범 커버, 포장, 명함에서는 제 몫을 합니다. 비상구 표지판에는 어울리지 않습니다. 어떤 설정이든 천 장을 주문하기 전에 인쇄물을 실제 휴대폰으로 테스트하십시오. 스튜디오는 내보내기 버튼 옆에서 같은 말을 하며, 진심으로 그렇게 말합니다.
| 코드의 부분 | 디더링 코드에서의 처리 | 이유 |
|---|---|---|
| 파인더 패턴 (모서리 사각형 세 개) | 단색으로 그림, 디더링하지 않음 | 스캐너는 무엇보다 먼저 코드를 찾고 방향을 잡아야 함 |
| 타이밍 선, 정렬 사각형, 형식과 버전 띠 | 단색으로 그림, 디더링하지 않음 | 구조적. 오류 정정은 찾지 못한 코드를 복구할 수 없음 |
| 데이터와 오류 정정 모듈 | 각 모듈의 중앙 블록을 강제, 나머지는 사진을 담음 | 스캔 거리에서 카메라가 보는 것은 모듈의 평균 계조 |
| 강제 블록 주변 픽셀 | 보상을 위해 오차 확산으로 이동됨 | 국소 평균을 맞게 유지하여 강제된 점이 얼룩 속에 숨게 함 |
| 여백 영역 | 밝게, 건드리지 않음 | 스캐너는 빈 여백을 이용해 코드의 가장자리를 찾음 |
자주 묻는 질문
사진이 그냥 코드 뒤에 놓인 건가요?
아니요. 코드와 사진은 한 번의 패스로 생성됩니다. 그림이 디더링되고, 코드가 값을 필요로 하는 곳에서 픽셀이 강제되며 그 오차가 이웃으로 확산됩니다. 이미지는 하나이며 다른 것 위에 얹힌 층이 아닙니다.
왜 모듈당 9픽셀인가요?
각 모듈에 9×9 블록을 주어, 가변 크기의 강제 코어를 담으면서도 그림을 위한 픽셀을 남길 만큼 크기 때문입니다. 그 블록의 얼마만큼을 강제할지는 균형 설정이 결정합니다.
일반 휴대폰으로 스캔되나요?
예. 설계 대상인 페이로드와 이미지에 대해서는 그렇고, 모든 빌드는 두 개의 독립된 디코더로 일곱 가지 시뮬레이션된 카메라 거리에서 검사됩니다. 그래도 신뢰성과의 절충이므로 하나를 인쇄해 본인 휴대폰으로 테스트하십시오.
긴 링크는 왜 그림을 망치나요?
텍스트가 길면 버전이 높아져 같은 사각형에 더 많고 더 작은 모듈이 들어갑니다. 각 모듈이 사진 픽셀에 쓸 공간이 줄고, 대략 49×49 모듈을 넘으면 그림이 사라집니다. 짧은 리디렉션 링크를 쓰십시오.
사각형은 한 번만 인쇄하세요. 목적지는 나중에 정하면 됩니다. SWAPQR은 정적 QR 코드를 무료로 만들어 줍니다. 모든 스타일 옵션이 포함되며 계정도, 워터마크도 없습니다. 유료 플랜을 사용하면 코드가 동적으로 바뀝니다. 인쇄된 사각형은 그대로 두고 목적지를 변경할 수 있으며, 일별·기기별로 얼마나 자주 스캔되었는지 확인할 수 있습니다.
브라우저에서 QR 코드 만들기