# 문서 스캐너 — 종이 사진을 반듯하게

종이를 찍으십시오. 스캔한 것처럼 생긴 것이 돌아옵니다.

> 휴대폰으로 찍은 종이 사진을 반듯하고 고르게 밝은 PDF로 만듭니다. 네 모서리는 찾아 주고, 원근은 되돌리고, 그림자는 나눠서 걷어 냅니다. 전부 브라우저 안에서 돌아갑니다. 아무것도 업로드되지 않습니다.

이 페이지는 브라우저 안에서만 동작하는 대화형 도구입니다(https://abox.tools/ko/문서-스캔/). 도구에 넘긴 어떤 것도 업로드되지 않습니다. 아래는 이 페이지가 도구에 대해 글로 설명하는 내용 전부입니다. 도구를 쓰려면 이 주소를 여세요.

## 문서는 **절대 업로드되지 않습니다**. 서버가 아예 없으니까요.

사진을 디코딩하고, 반듯하게 펴고, 정리하고, PDF로 쓰는 일은 모두 이 브라우저가 산술과 이미 들어 있는 코덱만으로 합니다. 이 도구에는 네트워크 기능이 아예 없어서 가져올 것도 보낼 것도 없습니다. 여기서 그것이 중요한 이유는 사람들이 어떤 종이를 찍는지에 있습니다. 여권, 급여명세서, 임대차 계약서, 관공서가 ‘스캔해서 보내라’고 한 서류입니다.

- ✗ 업로드 없음
- ✗ 계정 없음
- ✗ 워터마크 없음
- ✓ 오프라인 작동
- ✓ 오픈 소스

## 휴대폰 카메라로 문서 스캔하는 법

1. **종이를 찍으십시오.** 위에서, 종이 전체가 화면에 들어오고 네 모서리가 보이거나 거의 보이게 찍으십시오. 정면일 필요도, 빛이 고를 필요도 없습니다. 기울기와 그림자야말로 이 도구가 있는 이유입니다. 중요한 것은 화면을 채우는 것입니다. 방 건너편에서 찍은 종이에는 되살릴 세부가 없습니다.
2. **네 모서리를 확인하십시오.** 사진을 읽을 때 찾아 주고, 확신이 서지 않으면 페이지가 그렇게 말합니다. 종이와 같은 색 책상 위의 종이는 정말로 가장자리가 잘 보이지 않습니다. 사진 아무 데나 누르면 가장 가까운 모서리가 손가락으로 오고, `Tab`으로 하나를 잡아 화살표 키로 옮길 수도 있습니다.
3. **빛을 어떻게 할지 고르십시오.** ‘색, 고르게’는 종이의 밝기를 지면 전체에 걸쳐 재서 나눠 걷어 냅니다. 그래서 그림자가 사라져도 도장이나 서명은 제 색을 지킵니다. ‘흑백’은 거기서 더 나아가고, 스캔을 메일로 보낼 만큼 작게 만드는 것이 바로 그것입니다. 화면에 보이는 것이 실제 결과이고, 파일을 쓰는 것과 같은 코드가 만든 것입니다.
4. **나머지 장을 더하십시오.** 더하는 사진마다 같은 문서의 다음 장이 되고, 순서는 목록에 놓인 대로이며, 각 장은 자기 모서리를 지킵니다. 띠에 있는 장의 화살표가 그 장을 앞이나 뒤로 옮깁니다.
5. **PDF를 저장하고, 보내기 전에 열어 보십시오.** 문서는 여기, 이 페이지의 메모리에서 만들어집니다. 그것을 만드는 데 업로드된 것은 없고, 그것에 대해 어디에 알려진 것도 없습니다.

## 자세한 설명

[휴대폰으로 문서 스캔하는 법](https://abox.tools/ko/가이드/휴대폰으로-문서-스캔하기/): 종이를 찍은 사진과 그 종이를 스캔한 것을 가르는 것: 기울기, 고르지 않은 빛, 그리고 파일 크기입니다. 사진을 어떻게 찍고, 그다음 무엇을 고치고, 왜 그 어느 것에도 서버가 필요 없는지.

## 상자 속 다른 도구

- [동영상에서 오디오 추출](https://abox.tools/ko/동영상-오디오-추출/): 동영상을 놓으면 소리만 가져갑니다. 화면은 한 번도 디코딩되지 않고, 아무것도 업로드되지 않습니다.
- [오디오 자르기](https://abox.tools/ko/오디오-자르기/): 재생하면서 남길 곳에 표시하십시오. 표시한 만큼이 한 파일로, 말한 자리에서 잘려 돌아옵니다.
- [오디오 편집](https://abox.tools/ko/오디오-편집/): 거꾸로 돌리고, 배속을 바꾸고, 작게 녹음된 소리를 키웁니다. 전부 내 기기 안에서.
- [PDF 합치기 & 나누기](https://abox.tools/ko/pdf-합치기/): 서버를 한 바퀴 돌지 않고 페이지를 옮깁니다.

## 자주 묻는 질문

### 제 문서가 어딘가로 업로드되나요?

아닙니다. 사진을 디코딩하고 반듯하게 펴고 정리해서 PDF로 쓰는 일은 모두 이 브라우저가 이 기기의 하드웨어에서 합니다. 이 도구에는 네트워크 기능이 아예 없어서 무엇을 가져오지도, 보내지도 않습니다. 그리고 페이지의 `Content-Security-Policy`에는 접속할 수 있는 주소가 모두 적혀 있는데 그중 이 사이트의 것은 하나도 없습니다. 페이지를 한 번 불러온 다음 인터넷을 끊어도 그대로 동작합니다.

### 모델 없이 종이의 모서리를 어떻게 찾나요?

사각형을 이루는 네 개의 길고 곧은 가장자리를 찾습니다. 사진을 줄이고 기울기를 구합니다. 이미지가 어디에서 어느 방향으로 변하는지입니다. 그리고 가장자리에 놓인 픽셀마다 자기가 놓일 직선에 표를 던집니다. 강한 직선들을 짝지어 후보 사각형을 만들고, 후보마다 네 변을 따라 걸으며 각 변 아래에 실제로 가장자리가 얼마나 있는지, 그리고 그 넷이 한 물건의 경계인지를 물어 점수를 매깁니다. 종이는 주변보다 밝거나 어둡되 네 변에서 모두 같은 방향으로 그러한데, 그것이 글줄 한 줄을 종이의 아랫변으로 착각하지 않게 해 줍니다. 가중치도 없고, 내려받는 것도 없으며, 어떤 문서가 들어와도 산술은 같은 산술입니다.

### 찾아 준 모서리가 틀렸습니다. 어떻게 하죠?

끌어서 옮기십시오. 모서리는 출발 위치일 뿐 결코 결정이 아닙니다. 스캔은 네 모서리가 최종적으로 놓인 자리에서 뜹니다. 사진 아무 데나 누르면 가장 가까운 모서리가 손가락으로 뛰어오는데, 작은 손잡이를 정확히 짚는 것보다 쉽습니다. 화살표 키는 초점이 놓인 모서리를 한 픽셀씩 옮깁니다. 모서리가 찾아낸 것이 아니라 추측일 때도 페이지가 말해 주고, 띠에서 그 장을 표시해 둡니다. 제 색과 비슷한 책상 위에 놓인 종이가 흔한 이유인데, 거기에는 찾을 가장자리가 정말로 거의 없기 때문입니다.

### 반듯하게 편 종이가 왜 눌리지 않고 제 모양으로 나오나요?

모양을 가장자리에서 재는 것이 아니라 원근에서 되살리기 때문입니다. 비스듬히 찍은 종이는 먼 쪽 가장자리가 짧아 보입니다. 그래서 뻔한 방법 — 마주 보는 가장 긴 변 한 쌍을 골라 그것을 비율이라고 부르는 것 — 은 눈에 띄게 뭉툭한 A4를 만듭니다. 웹 스캐너 대부분이 그렇게 줍니다. 사실 사각형을 찍은 사진에는 카메라가 평범한 카메라이기만 하다면 그 사각형의 종횡비와 카메라의 초점 거리를 함께 되살리기에 충분한 정보가 들어 있습니다. 2003년 Zhang과 He의 결과이고, `src/geometry.js`가 하는 일입니다. 정면으로 찍은 사진에는 원근이랄 것이 없고 필요하지도 않습니다. 그때는 가장자리가 정확하기 때문입니다. 그래서 그쪽으로 물러나고, 어느 쪽이 답했는지를 페이지가 말해 줍니다.

### ‘정리’는 이미지에 실제로 무엇을 하나요?

빛을 나눠서 걷어 냅니다. 종이 자체의 밝기를 지면 전체에 걸쳐 잽니다. 격자로 나눈 칸마다 밝기의 높은 백분위수를 취하는데, 글자는 그 값을 움직이기에는 너무 어둡고 너무 성깁니다. 그리고 각 픽셀을 그 지점에서 추정한 종이 밝기로 나눕니다. 남는 것은 잉크이고, 빛이 고르며, 그림자도 가장자리 어두워짐도 없습니다. 이것은 대비를 올리는 것과 다릅니다. 찍은 종이의 대비를 올리면 밝은 쪽은 하얗게, 어두운 쪽은 새까맣게 되고, 어두운 쪽에 적힌 글씨는 읽을 수 없게 됩니다. ‘자동 레벨’이 이런 사진을 좋게 만들기는커녕 나쁘게 만드는 이유입니다.

### 흑백 모드는 왜 그렇게 훨씬 작은가요?

색이 둘인 이미지는 천육백만인 이미지에 견주면 정말로 데이터의 극히 일부이고, 여기서도 그렇게 저장하기 때문입니다. 픽셀당 1비트를 바이트마다 여덟 개씩 묶어 정확하게 압축합니다. 흑백 이미지를 JPEG으로 만드는 것이 아닙니다. 같은 문서에서 컬러 모드보다 열여덟 배쯤 작게 나와서, 스무 장짜리 계약서가 십오 메가바이트쯤이 아니라 일 메가바이트 아래로 떨어집니다. 임계값은 Sauvola의 것으로, 각 픽셀을 지면 전체의 한 숫자가 아니라 제 이웃의 평균과 퍼짐에 견주어 정합니다. 그것이 그림자 속 글씨를 지켜 줍니다. 중간 톤이 없으니 사진이 들어간 장은 다른 모드를 써야 합니다.

### 여러 장을 한 PDF에 넣을 수 있나요?

예. 더하는 사진마다 다음 장이 되고, 순서는 목록에 놓인 대로이며, 각 장은 자기 모서리를 지킵니다. 그래서 차례로 찍은 종이 더미가 문서 하나가 됩니다. 띠에 있는 각 장의 화살표가 그 장을 앞뒤로 옮깁니다. 정리 설정을 모든 장이 함께 쓰는 것은 일부러 그런 것입니다. 한 문서 안에서 서로 다르게 정리된 장들은 두 개의 문서처럼 보입니다.

### 글자를 읽어서 PDF를 검색할 수 있게 해 주나요?

아닙니다. 텍스트 층도 없고 문자 인식도 없습니다. 나오는 것은 종이의 그림이 한 장에 얹힌 것입니다. 제대로 하려면 OCR 엔진이 필요한데, 그것은 수십 메가바이트짜리 모델을 내려받는 일입니다. 그리고 급여명세서를 읽기도 전에 모델을 가지러 가는 문서 스캐너는 급여명세서에 대해 집에 전화할 이유가 있는 문서 스캐너일 것입니다. 글자가 필요하다면, 흑백 모드가 만드는 파일이 이 기기의 OCR 소프트웨어가 가장 잘 다루는 바로 그런 파일입니다.

### 흐릿하게 나왔습니다. 왜죠?

거의 언제나 사진 속에서 종이가 작았기 때문입니다. 미리보기 아래 칸이 종이가 화면의 얼마를 채웠는지, 그리고 그 크기의 종이에서 인치당 몇 점쯤 되는지를 말해 줍니다. 대략 150 DPI 아래로 내려가면 인쇄한 스캔이 흐물흐물해 보이고, 파일에 애초에 없던 세부에 대해서는 어느 도구도 해 줄 것이 없습니다. 확대 대신 가까이 가고, 가만히 들고, 버튼을 누르기 전에 카메라가 종이에 초점을 맞추게 하십시오. 흔들림이 나머지 원인이고, 그것도 되살릴 수 없습니다.

### 무료인가요? 계정이 필요한가요?

무료이고, 계정도 로그인도 체험판도 장수 제한도 워터마크도 없습니다. 사진 크기에도 제한이 없습니다. 그 값을 치르는 서버가 없기 때문입니다. 일은 이 기기에서 일어납니다. 이 사이트는 광고로 운영되고, 광고 쪽에는 문서에 대한 것이 전해지지 않습니다.

## 이 약속을 직접 확인하는 방법

- **문서가 갈 곳이 없습니다.** Content-Security-Policy에는 이 페이지가 접속할 수 있는 주소가 모두 적혀 있고, 그중 이 사이트의 것은 하나도 없습니다. 사진이 모일 만한 엔드포인트가 여기에는 없고, 설령 있다 해도 그것을 보낼 코드가 없습니다.
- **모델이 없으니 내려받을 것도, 물어볼 곳도 없습니다.** 종이의 네 모서리를 찾는 일은 산술로 합니다. 이미지의 기울기, 그 안의 직선들에 대한 투표, 그리고 이긴 사각형의 각 변 아래에 실제로 무엇이 있는지에 대한 확인입니다. 가중치도, 추론 런타임도, 처음 쓸 때 받아 오는 것도 없고, 다른 사람의 문서에서 다르게 동작할 것도 없습니다. `src/detect.js`를 보십시오.
- **문서에는 날짜도, 작성자도, 기기 이름도 들어가지 않습니다.** 스캔은 사람들이 다른 사람에게 보내는 것이고, 대개 관공서가 요구해서 보냅니다. 페이지 자체를 빼면 PDF에 쓰이는 것은 이 도구의 이름뿐이고, 제목을 입력하면 그것이 더해집니다. 만든 날짜도, 작성자도, 일련번호도 없고, 시계나 파일 이름이나 컴퓨터에서 끌어낸 것도 없습니다. `src/document.js`를 보십시오.
- **여기서는 아무것도 가져오지 않습니다.** `src/` 어디에도 `fetch`도, `XMLHttpRequest`도, `sendBeacon`도 없습니다. 하는 일은 `getImageData`와 바이트를 도는 몇 개의 반복문, 그리고 브라우저 자신의 JPEG 인코더입니다. 모두 이미 이 기기에 설치되어 있는 것들입니다.
- **오프라인에서 작동합니다.** 네트워크를 끊어도 이 도구는 그대로입니다. 애초에 네트워크 단계가 없었기 때문입니다. 가장 간단한 증거이고, 여권을 스캔하기 전에 한 번 해 볼 만한 일입니다.

**직접 확인해 보세요.** 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 `dist` 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다: https://github.com/A-Box-of-Tools/website

먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 `config/site.toml`, 모델 없이 모서리를 찾는 방법은 `src/detect.js`, 반듯하게 펴는 일은 `src/warp.js`, 고르지 않은 빛을 나눠서 걷어 내는 일은 `src/clean.js`입니다.
