PSD 파일은 포토샵의 정답지다. UI는 없다.
요약
이 글은 Photoshop 파일 형식(PSD)의 내부 구조와 복잡한 블렌딩 수학 구현에 대한 기술적 분석입니다. 특히, Rust로 작성된 오픈 소스 도구 [PhotoCraft]를 사용하여 PSD 파일을 클린룸 방식으로 재구성하고, Adobe가 저장하는 병합 이미지 결과물과 비교 검증하는 과정을 설명합니다.
핵심 포인트
- PSD 파일은 단순 레이어 외에 '정답지' 역할을 하는 평탄화 복사본을 포함한다.
- PhotoCraft는 Rust로 구현된 PSD의 오픈 소스 클린룸 재구현 도구이다.
- 실제 PSD 파일을 분석하여 블렌딩 모드 수학적 정확성을 검증하는 과정을 제시했다.
이번 주에 나는 손으로 Photoshop 파일을 만들었다. 390바이트 크기에, 두 개의 회색 레이어와 그 위에 Soft Light로 설정된 레이어가 있다. 나는 의도적으로 파일의 저장 미리보기(saved preview)를 단색 마젠타로 채웠고, 그래서 단순히 미리보기만 보여주는 어떤 리더는 속을 것이다.
그 리더는 마젠타를 무시하고 레이어들로부터 이미지를 재구성했으며, 나에게 32라는 회색 값을 돌려주었다. CSS의 soft-light 뒤에 숨겨진 W3C 공식은 동일한 두 개의 레이어에 대해 15를 준다.
그 리더는 PhotoCraft의 명령줄 도구였다. 이 도구는 자신을 순수 Rust로 구현된 Photoshop의 오픈 소스 클린룸 재구현이라고 부른다. 해당 레포지토리는 9월 30일에 생성되었고, 일주일 만에 2,200개의 스타를 받았으며, 10월 5일에 v0.2.0을 출시했다. 자체 README에는 초기 알파 버전이며 '일상적인 전문 작업용 Photoshop 대체품은 아니다'라고 명시되어 있다.
나는 한 가지 질문에 저녁 시간을 보냈다. 이렇게 어린 프로젝트가 어떻게 블렌딩 수학(blend math)을 정확하게 구현하면서도, 첫 사용자들은 기본 기능이 깨진다고 말하는 걸까?
파일 안에 있는 정답지
PSD는 단순히 레이어만 담고 있지 않다. Photoshop이 '최대 호환성으로 저장(Maximize Compatibility on)'할 때, 전체 이미지의 평탄화된 복사본(flattened copy)도 함께 기록한다. 즉, 그 레이어들에 대한 자체 렌더링 결과물이다. 이와 같은 파일 하나하나는 정답지가 뒷면에 스테이플러로 박힌 질문과 같다.
PhotoCraft의 테스트 스위트 역시 이를 기반으로 구축되었다. crates/io/tests/corpus.rs는 실제 PSD 파일을 열고, PhotoCraft 자체 컴포지터(compositor)를 사용해 레이어들을 평탄화한 다음, 그 결과를 Photoshop이 저장한 병합된 이미지와 비교한다. 픽셀은 2/255 이내의 오차 범위 내에서 통과된다. 병합 이미지가 없이 저장된 파일의 경우, Photoshop이 임베드하는 작은 JPEG 썸네일로 대체되는데, 이것 역시 Photoshop의 렌더링 결과물이다.
나는 외부적으로 이를 확인했다. MIT 라이선스가 적용된 psd-tools 프로젝트에서 블렌딩 모드 테스트 파일 14개를 가져왔고, 이들은 모두 Photoshop에 의해 저장되었다. 나는 각 파일의 병합 이미지를 개별적으로 디코딩하는 짧은 Node 스크립트를 작성했다. 그리고 PhotoCraft의 CLI를 사용해 모든 파일을 레이어로부터 렌더링하고 두 결과를 비교했다. 예시:
pt/multiply.psd 4096 px exact 3993 max diff 1/255
pt/overlay.psd 4096 px exact 3353 max diff 1/255
pt/soft-light.psd 4096 px exact 3346 max diff 2/255
...
총 14개의 파일이 Photoshop의 렌더링 결과와 2/255 이내로 일치했습니다. 이것만으로도 충분히 놀랍지만, 이 파일들은 PhotoCraft가 자체적으로 테스트하는 코퍼스에 포함되어 있으므로 통과했다는 것은 이미 그 테스트들이 보장하는 것입니다. 흥미로운 부분은 이 코퍼스가 코드에게 무엇을 가르쳤는지입니다.
클린룸(Clean-room) 방식이란 출력물로부터 학습한다는 의미
이 프로젝트의 규칙은 AGENTS.md와 docs/contributing.md에 명시되어 있듯이, Photoshop은 동작과 외관만을 연구 대상으로 삼고 있습니다. 복사된 코드, 셰이더, 프로파일 또는 에셋은 사용하지 않습니다. 구현은 공개 사양(Adobe의 PSD 사양, ICC, 블렌드 모드를 위한 ISO 32000)과 관찰을 통해 이루어집니다. PSD 사양이 침묵하는 부분에서는 psd 크레이트(psd crate)의 README가 MIT 라이선스가 적용된 psd-tools 및 ag-psd 문서를 따른다고 명시합니다.
관찰은 여기에서 비유적인 표현이 아닙니다. crates/compose/src/psblend.rs에는 Photoshop 고유 버전의 Vivid Light와 Hard Mix가 포함되어 있으며, 헤더에 따르면 이들은 해당 psd-tools 파일들에서 Photoshop이 렌더링한 합성 결과물로부터 파생된 것입니다. 한 가지 사례를 들자면, 흰색 배경 위에 검은색 Vivid Light 레이어를 올린 경우입니다. 교과서적인 color-burn 브랜치는 흰색을 반환합니다. 하지만 PhotoCraft는 Photoshop의 저장된 렌더링 결과가 보여주는 대로 검은색을 반환합니다. 제가 이 케이스를 실행했을 때 0이 나왔습니다.
Soft Light도 마찬가지입니다. crates/color/src/blend.rs에는 W3C 정의와 다른 부분이 있는 Photoshop Soft Light가 유지되어 있습니다. 여기에 CLI를 통해 돌려본 저의 직접 제작 파일들과 두 공식(formula)을 나란히 비교합니다:
$ node cases.mjs
sLit backdrop 4 source 254 -> 32 css-w3c 15 ps-formula 32
sLit backdrop 26 source 230 -> 71 css-w3c 67 ps-formula 71
...
저는 8비트 값의 모든 65,536 쌍을 스캔했습니다. 두 공식은 이 중 4,579개에서 최대 17단계까지 불일치하며, 항상 밝은 레이어 아래 어두운 배경에서 이런 차이가 발생합니다. 만약 mix-blend-mode: soft-light를 사용하여 Photoshop 목업(mockup)을 맞추려 했는데 그림자 부분이 잘못 나왔다면, 이것이 그 정직한 이유 중 하나입니다.
규칙의 대가는 카메라 RAW 디코더에서 드러납니다. Issue #83에서는 Nikon의 압축된 NEF 파일이 여전히 임베디드 JPEG로만 열리는 이유를 설명합니다. 그 이유는 디코더가 파일에 포함되지 않은 Huffman 테이블을 필요로 하는데, 저자가 찾은 유일한 설명 자료는 GPL 디코더 소스나 이를 바탕으로 작성된 글들이었기 때문입니다. 그래서 작업을 중단했습니다. 이것은 프로젝트 자체의 입장이며 법적 의견이 아니므로 저는 어떠한 의견도 제시하지 않습니다.
정답지가 없는 것들
제 주장은 이렇습니다. PhotoCraft는 파일이 평가할 수 있는 영역에서 가장 빠르게 움직이며, 아무것도 할 수 없는 곳에서 무너집니다.
그 속도는 실재합니다. 제가 이를 복제했을 때, 레포지토리는 제 계산으로는 약 231,000줄의 Rust 코드를 담고 있었고, 빌드 체크가 강제하는 계층 구조로 이루어진 수십 개의 크레이트(crate)와 748개의 명령이 등록된 CLI를 가지고 있었습니다. 이 레포지토리 자체 커밋 트레일에 따르면, main 브랜치의 236개 커밋 중 138개가 Claude와 공동 작성되었으며, AGENTS.md는 병렬로 작동하는 AI 에이전트를 위해 작성되었습니다. 잠들지 않는 평가자(grader)는 이러한 작업 방식에 적합합니다.
그러자 사람들이 이 앱을 사용하기 시작했습니다. HN 스레드에서 여러 테스터들이 기본적인 작업을 수행할 수 없었다고 말했고, 유지 관리자는 레포지토리가 준비되기 전에 공개되었다고 말합니다. 이 프로젝트의 로드맵은 자평에 따르면
파일 형식 자체도 픽셀보다 더 부드러운 면이 있습니다. 읽기는 Photoshop에 의해 평가되고, 쓰기는 다음에 파일을 여는 사람에 의해 평가됩니다. issue #200에서 한 사용자가 공개 PSD 파일 437개를 재저장했고, psd-tools는 그 출력물 중 36개를 읽을 수 없었습니다. 이 수정 사항은 v0.2.0 이후에 반영되었고, README에는 같은 변경 사항에서 '바이트 단위'라는 주장이 삭제되었습니다.
따라서 어떤 숫자를 읽는지 주의해야 합니다. psd-tools 파일 309개 중 307개가 재저장 후에도 동일하게 다시 열렸는데, 이는 PhotoCraft가 스스로에게 동의하는 것입니다. 이 세트에서 Photoshop 자체 렌더링과 일치하도록 강제된 최소치는 229입니다.
로드맵의 다음 단계는 마치 답변처럼 보입니다: 스크립트를 통해 실제 작업 30개에서 50개를 처음부터 끝까지 실행하고, 빌드마다 각각을 Photoshop 출력물과 비교하여 확인하는 것입니다. 이것은 워크플로우를 위한 정답지입니다. 크롭 프레임이 어떻게 느껴지는지를 포착할 수 있을지가 제가 지켜볼 베팅입니다.
내가 실행한 것과 실행하지 않은 것
저는 데스크톱 앱을 실행하거나 소스에서 빌드하지 않았습니다. v0.2.0 GitHub 릴리스에서 macOS CLI zip 파일을 다운로드하여, 그 해시를 릴리스의 SHA256SUMS.txt와 비교했고, Developer ID로 서명되었으며 notarized 되었음을 확인했습니다. 그런 다음 임시 폴더에서 다음과 같이 실행했습니다:
./photocraft-cli --version # photocraft-cli 0.2.0 (ad8632173, 2026-10-05)
./photocraft-cli info t-soft.psd # 내가 만든 파일: 두 개의 레이어, "blend": "Soft Light"
./photocraft-cli convert pt/soft-light.psd soft-light.ppm
...
저는 호스팅된 웹 버전을 찾지 못했습니다. 릴리스는 사용자가 직접 호스팅하는 zip 형태로 WebAssembly 빌드를 제공합니다.
제 숫자에 대한 두 가지 제한 사항이 있습니다. psd-tools 파일은 PhotoCraft 자체 코퍼스에 포함되어 있습니다. 그리고 저의 Soft Light 검사는 제가 실행하지 않은 공식(formula)과 PhotoCraft를 비교한 것이지, Photoshop과 비교한 것이 아닙니다.
명세가 없는 상태에서 동작을 복제해야 했을 때, 무엇을 정답지로 사용했고, 명세가 없었던 부분은 어떻게 처리했습니까?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기