본문 바로가기

IT & AI

사진이 보이는데도 스캔되는 디더링 QR 코드의 원리

728x90

사진이 보이는데도 스캔되는 디더링 QR 코드의 원리

AI 뉴스 썸네일
AI 뉴스 썸네일

QR 코드 안에 사진을 넣으면서 스마트폰이 읽어야 할 정보도 남길 수 있을까요? 개발자 Andrew Taylor는 데이터 모듈의 중심을 보존하고, 그 주변에 오차 확산 디더링을 적용하는 방법을 공개했어요. 장식용 이미지를 단순히 덮는 방식보다 QR 코드가 어떤 지점을 읽는지 먼저 이용한 접근이에요. 1

핵심 요약

구분핵심왜 볼 만한가요
공간 활용데이터 모듈을 3×3 픽셀로 나누고 중심 픽셀에 QR 정보를 남겨요나머지 8개 픽셀로 사진의 밝기와 형태를 표현할 수 있어요
이미지 처리고정된 QR 픽셀의 밝기 오차를 주변 8개 픽셀로 먼저 퍼뜨려요무작위 점처럼 보이는 잡음을 줄이고 사진의 윤곽을 살려요
판독 구조탐색 패턴과 정렬 패턴은 선명하게 유지해요스캐너가 코드의 위치와 모듈 중심을 찾을 기준을 보존해요
사용 조건화면 크기, 인쇄 상태, 조명, 카메라에 따라 판독률이 달라져요한 기기에서 읽힌 결과만으로 실제 환경을 판단하면 위험해요

1. QR 데이터의 중심을 남기고 주변에 사진을 그려요

QR 코드는 모든 검은색과 흰색 사각형을 같은 용도로 쓰지 않아요. 모서리의 큰 탐색 패턴과 정렬 패턴은 카메라가 코드의 위치와 방향을 찾는 데 쓰여요. 나머지 데이터 모듈에는 실제 문자열과 복구용 정보가 들어가요. 스캐너는 먼저 기능 패턴으로 격자를 맞춘 뒤 각 데이터 모듈의 중심을 읽어요. 2

이 성질을 이용하면 데이터 모듈 전체를 큰 사각형으로 칠할 필요가 없어요. 원문 예시는 모듈 하나를 3×3 픽셀로 나누고 중앙 1픽셀에만 QR 값을 남겨요. 주변 8픽셀에는 사진을 흑백으로 줄인 결과를 배치해요. 멀리서 보면 얼굴이나 사물의 형태가 보이고, 스캐너에는 규칙적인 중심점 배열이 남아요.

728x90

다만 중앙 픽셀은 사진의 원래 밝기와 관계없이 검정이나 흰색으로 고정돼요. 어두운 얼굴 영역에 흰 점이 찍히거나 밝은 배경에 검은 점이 박힐 수 있어요. 픽셀 9개 가운데 1개가 QR 데이터에 따라 정해지기 때문에 그대로 합치면 소금과 후추를 뿌린 듯한 잡음이 생겨요.

두 번의 오차 확산으로 고정 픽셀의 잡음을 줄여요

Floyd-Steinberg 디더링은 흑백 두 색만으로 중간 밝기를 표현하는 방법이에요. 원본 픽셀을 검정 또는 흰색으로 바꾼 뒤 생긴 밝기 차이를 아직 처리하지 않은 주변 픽셀에 나눠 줘요. 한 영역 전체에서 평균 밝기가 원본과 가까워지도록 만드는 방식이에요.

디더링 QR 코드는 이 과정을 두 번 사용해요. 첫 번째 단계에서는 QR 정보 때문에 색이 고정된 중앙 픽셀을 먼저 처리해요. 고정 색상과 원래 사진 사이의 오차를 주변 8픽셀로 퍼뜨려요. 두 번째 단계에서는 보정된 전체 이미지에 일반적인 Floyd-Steinberg 디더링을 적용해요. 중앙의 흰 점 하나를 지울 수는 없지만, 주변을 조금 더 어둡게 배치해 눈에 띄는 밝기 차이를 완화할 수 있어요. 2

이 방식은 QR 데이터를 이미지 뒤에 숨기지 않아요. 읽어야 할 픽셀은 그대로 두고, 사람이 보는 주변 픽셀을 조정해 시각적 충돌을 줄여요. 생성기는 QR 방향과 인코딩 설정도 바꿀 수 있어요. 같은 문자열이라도 모듈 배열이 달라지면 사진의 주요 부분과 겹치는 잡음 위치가 달라져 더 나은 조합을 찾을 수 있어요. 3

오류 정정을 많이 쓰면 오히려 스캔 여유가 줄어요

QR 코드에는 일부 모듈이 손상돼도 내용을 복구하는 오류 정정 기능이 있어요. 중앙 로고가 있는 QR 코드도 이 여유를 이용해요. 생성기 역시 사진과 크게 충돌하는 데이터 모듈 일부를 바꾸는 선택지를 제공해요.

원문 실험에서는 모듈을 추가로 바꿔도 사진 품질이 크게 좋아지지 않았어요. 고정 픽셀의 오차를 이미 주변에 분산했기 때문이에요. 반면 스캐너가 복구해야 할 오류는 늘어나요. 구겨진 종이, 낮은 조도, 흐린 초점처럼 다른 손상에 대응할 여유가 줄어드는 셈이에요. 보기 좋은 결과를 얻으려고 오류 정정을 미리 소진하면 실제 배포 환경에서 판독성이 빠르게 떨어질 수 있어요.

화면에서 읽힌 뒤에도 인쇄 조건을 따로 확인해야 해요

노트북 화면에 크게 띄운 QR 코드를 최신 스마트폰으로 읽는 테스트는 조건이 좋아요. 종이에서는 잉크 번짐과 접힘이 생길 수 있고, 조명이 어두우면 모듈 경계가 흐려져요. 카메라 해상도와 자동 초점 성능도 기기마다 달라요. 포스터처럼 크게 출력할 때와 작은 전단에 넣을 때 같은 설정을 쓰기 어려운 이유예요.

QR 코드 바깥의 여백도 필요해요. 생성기가 만든 작은 이미지에 여백이 없더라도 실제 배치에서는 탐색 패턴 주변에 배경 공간을 남겨야 해요. 웹페이지에서 픽셀 이미지를 확대할 때 브라우저 보간으로 경계가 흐려질 수 있어요. 이 경우 CSS의 `image-rendering` 속성으로 보간 방식을 조정할 수 있어요. 4

실사용 전에는 목표 크기로 출력한 뒤 여러 거리와 각도에서 확인하는 편이 안전해요. 밝은 실내와 낮은 조도에서 각각 시험하고, 서로 다른 제조사의 스마트폰도 섞어야 해요. 이미지가 조금 덜 선명해지더라도 기능 패턴, 바깥 여백, 오류 정정 여유는 충분히 남겨야 해요.

왜 중요한가요

이 실험은 QR 코드 디자인을 로고 삽입이나 색상 변경에서 한 단계 더 세밀하게 다뤄요. 스캐너가 실제로 읽는 위치를 보존하면서 사람이 보는 픽셀에 별도의 정보를 배치해요. 데이터 표현 규칙과 이미지 처리 알고리즘을 함께 이해하면 기능을 유지한 시각 디자인을 만들 수 있다는 사례예요. 구현 코드는 공개 저장소에서 확인할 수 있어요. 5

브랜드 캠페인이나 전시물에서는 QR 코드 자체가 이미지 일부로 보일 수 있어 활용도가 있어요. 대신 결과물의 품질 기준은 사진의 선명도만으로 정할 수 없어요. 최종 크기, 재질, 조명, 촬영 거리에서 반복해서 읽히는지가 더 중요해요. 디자인팀과 개발팀이 함께 판독 조건을 정하고 실제 출력물로 테스트해야 하는 이유예요.

참고 자료

  1. 디더링 QR 코드 만들기 — GeekNews
  2. Making your own dithered QR codes — Andrew Taylor
  3. Dithered QR code generator — Andrew Taylor
  4. CSS image-rendering — MDN Web Docs
  5. dithered-qr-codes source code — Codeberg
728x90