기술 · 실용 가이드
폴더가 분리된 darktable 사진에서 JPEG 별점을 RAW로 옮기기
날짜별 RAW 폴더와 그 안의 Jpgs 하위 폴더를 그대로 유지하세요. 검토 가능한 계획을 만들어 명시적으로 기록된 별점을 기존 darktable 사이드카 파일에 옮긴 다음, 변경 사항을 라이브러리에 불러옵니다.

JPEG에 별점을 매겨 두면 방대한 사진 보관 자료를 더 쉽게 정리할 수 있습니다. 대응하는 RAW가 한 단계 위 폴더에 있으면 일이 하나 더 생깁니다. 사진 선별은 끝났지만, 실제로 보정할 파일에는 그 판단을 아직 반영해야 하기 때문입니다. 별점을 옮기려고 수년 치 폴더부터 재정리할 필요는 없어야 합니다.
이 가이드는 이러한 폴더 구조에 사용할 수 있는 완전한 보조 프로그램을 제공합니다. 각 날짜 폴더 안에서 파일을 짝짓고, 기존 RAW 사이드카 파일의 특정 별점 필드 하나를 갱신하면서 원본 사이드카 파일을 보관합니다. 마지막에는 별도의 darktable 다시 읽기 단계로 작업을 마무리합니다. 먼저 작은 날짜 폴더 하나로 시작하세요. 모든 짝을 확인하고 결과를 검증한 뒤 나머지 보관 자료로 범위를 넓힐 수 있습니다.
1. 각 날짜 폴더 안에서만 파일 짝짓기
지원하는 구조는 날짜 폴더 바로 안에 RAW가 있고, 그 날짜 폴더의 Jpgs 하위 폴더 바로 안에 대응하는 JPEG가 있는 형태입니다. 예를 들어 Photos/2024/2024-05/Jpgs/DSC01234.JPG는 Photos/2024/2024-05/DSC01234.ARW와 짝지어집니다. 별점이 기록될 파일은 Photos/2024/2024-05/DSC01234.ARW.xmp입니다.
공통 파일명 본체는 DSC01234이며, 철자와 대소문자까지 같아야 합니다. 다른 달의 폴더에 있는 또 다른 DSC01234.ARW는 별개의 후보이며, 해당 위치에서 짝을 찾지 못했다고 대신 사용하지 않습니다. 보조 프로그램은 선택한 사진 폴더 트리를 탐색하지만, 모든 짝짓기는 이 부모·자식 폴더 관계 안에서만 이루어집니다. 두 파일이 같은 촬영본인지는 판별하지 않습니다. 사용 중인 파일명과 폴더 구성이 실제로 같은 사진끼리 연결된다는 뜻인지 직접 확인해야 합니다.
기본값은 ARW와 Jpgs입니다. --raw-ext로 다른 RAW 확장자를 지정하고, --jpeg-subdir로 정확히 일치해야 할 다른 하위 폴더 이름을 지정할 수 있습니다. 파일명 본체가 같은 JPEG가 여러 개 있거나, 대응하는 RAW 형식이 여러 개이거나, 대소문자가 모호하거나, 번호가 붙은 편집 버전 사이드카 파일이 있을 가능성이 있으면 처리를 차단하고 검토하도록 합니다. Jpgs 안의 중첩 폴더는 이 규칙의 대상이 아닙니다.
대상 사이드카 파일에는 darktable 메타데이터가 이미 들어 있어야 합니다. 보조 프로그램은 편집 이력이 없는 파일을 빈 파일로 새로 만들거나, Lightroom 방식의 DSC01234.xmp를 추측해서 사용하지 않습니다. darktable은 가져오기 과정에서 다른 일부 사이드카 명명 방식도 읽을 수 있지만, 기본 사이드카 파일명에는 입력 이미지의 확장자가 포함됩니다. 이번 전송에는 실제로 존재하는 해당 기본 형식의 파일을 사용하세요.
2. JPEG 별점의 기준 출처 선택하기
darktable에서 무엇이든 준비하기 전에, 옮기려는 별점이 현재 어디에 저장되어 있는지 먼저 판단하세요. 보조 프로그램이 제공하는 명시적 출처 모드는 두 가지이지만, 흔히 마주치는 상황은 세 가지이며 준비 방법도 다릅니다.
별점이 원본 JPEG에 내장되어 있다면 --rating-source jpeg를 사용합니다. 해당 JPEG는 변경하지 마세요. 이 가이드의 원본 데이터를 준비한다는 이유만으로 JPEG를 가져오거나 JPEG 사이드카 파일을 만들지 마세요. 보조 프로그램은 명시적으로 기록된 XMP-xmp:Rating을 읽습니다. 다른 프로그램에 표시되는 별점이 모두 이 필드에 내장되어 있다고 가정하지 않습니다.
옮기려는 JPEG 별점이 현재 darktable 데이터베이스에 있다면 lighttable에서 해당 JPEG를 선택한 뒤 history stack > write sidecar files를 사용하세요. 그러면 현재 정보가 Jpgs/DSC01234.JPG.xmp와 같은 기본 형식의 사이드카 파일에 기록됩니다. darktable을 종료한 후 --rating-source sidecar를 선택합니다.
기존 JPEG 사이드카 파일에 원하는 별점이 이미 들어 있다면 그 파일을 기준 출처로 보존하세요. 앞 문단의 절차를 따르기 위해 오래된 darktable 데이터베이스의 내용으로 덮어쓰면 안 됩니다. sidecar 모드에서는 JPEG와 같은 폴더에 전체 JPEG 파일명 뒤에 .xmp가 붙은 파일이 정확히 존재해야 합니다. 확장자를 뺀 같은 파일명 본체의 짧은 사이드카 이름은 검색하지 않습니다.
내장 별점과 사이드카 별점을 모두 읽을 수 있다면 계획에 두 값이 함께 표시됩니다. 서로 다르면 경고에 차이가 표시되며, 명시적으로 선택한 출처 모드의 값이 우선합니다. 수정 시간을 비교해 자동으로 결정하지 않습니다. 선택한 출처에 별점이 없으면 다른 출처에 별점이 있어도 그 짝은 건너뜁니다. 정보가 없다는 이유로 0으로 취급하지 말고, 올바른 모드를 선택하여 새 계획을 만드세요.
3. 현재 편집 상태의 RAW 사이드카 파일을 준비한 뒤 darktable 종료하기
각 대상 사이드카 파일에 해당 RAW의 의도한 현재 편집 상태가 들어 있는지 확인하세요. 그 편집 내용이 darktable 데이터베이스에 있다면 lighttable에서 대상 일괄 처리 범위를 선택한 뒤 history stack > write sidecar files를 사용합니다. 오래된 사이드카 파일을 다시 가져오기 전에 이 작업을 하세요. RAW 사이드카 파일에 의도한 최신 편집 내용이 이미 들어 있다면 오래된 데이터베이스의 내용으로 덮어쓰지 말고, 계획을 만들 때 사용할 파일로 보존하세요. 적용 후에는 XMP에서 데이터베이스로 다시 읽는 절차를 사용합니다.
라이브러리에 실제로 없는 RAW라면 기존 위치에서 import > add to library를 사용한 다음, 기본 형식의 사이드카 파일이 기록되었는지 확인하세요. JPEG 메타데이터는 선택한 출처 분기에 필요한 것만 준비합니다. 전송 전에 중요한 라이브러리 데이터와 사이드카 파일을 백업해 두세요. 보조 프로그램이 나중에 만드는 백업은 자신이 변경하는 RAW 사이드카 파일만 보호합니다.
종료하기 전에 preferences > storage > XMP sidecar files를 열고 look for updated XMP files on startup을 켜세요. 이번 작업에서는 create XMP files를 never가 아닌 on import로 설정합니다. after edit 정책만으로는 아직 처리하지 않은 모든 RAW에 사이드카 파일이 이미 존재한다고 보장할 수 없습니다.
darktable을 종료하고 계획 생성, 검토, 적용이 끝날 때까지 닫아 두세요. 이 파일들을 다시 쓸 수 있는 다른 프로그램도 잠시 중지하세요. 그래야 준비한 상태를 유지할 수 있습니다. 이미지를 darktable에 추가한 뒤에는 데이터베이스 내용이 우선하여 외부에서 변경한 XMP를 다시 덮어쓸 수 있기 때문입니다.

4. Python, RDFLib, ExifTool 준비하기
Python 3.10 이상, RDFLib 7.6.0, ExifTool 실행 파일이 필요합니다. 보조 프로그램과 매니페스트를 위한 쓰기 가능한 새 작업 폴더를 준비하세요. 예제에서는 python3를 사용합니다. Windows에서 Python 명령이 py -3이라면 모든 단계에서 일관되게 py -3을 사용하세요.
보조 프로그램을 실행할 Python 환경과 같은 환경에 RDFLib를 설치하세요. 가상 환경을 사용하면 다른 프로젝트와 간편하게 분리할 수 있습니다. 가상 환경을 사용한다면 아래 모든 명령의 python3를 그 환경의 Python 실행 파일로 바꾸세요.
python3 -m pip install rdflib==7.6.0
python3 -c "import sys,rdflib; print(sys.version); print(rdflib.__version__)"
ExifTool은 공식 배포처에서 받아 해당 설치 안내를 따르세요. Windows에서는 명령줄에서 사용할 수 있도록 exiftool(-k).exe의 이름을 exiftool.exe로 바꾸고, 함께 제공되는 exiftool_files 폴더를 옆에 두세요. macOS나 Linux에서 이식형 Perl 배포본을 사용한다면 lib 디렉터리를 exiftool 스크립트 옆에 유지하고 Perl도 사용할 수 있어야 합니다.
ExifTool이 PATH에 있으면 보조 프로그램이 exiftool이라는 이름으로 찾을 수 있습니다. 그렇지 않으면 --exiftool로 실행 파일 경로를 지정하세요. Windows에서는 --exiftool "C:/Tools/ExifTool/exiftool.exe"와 같이 지정할 수 있습니다. macOS나 Linux에서는 실행 파일의 실제 경로를 사용하세요. 이 인수는 파일 경로이며, "perl exiftool" 같은 셸 명령이 아닙니다.
계획을 만들 때와 적용할 때 같은 실행 파일과 버전을 사용하세요. 그사이에 ExifTool을 업데이트하거나 옮겼다면, 기록된 실행 환경과 일치하도록 새 계획을 만드세요.
5. 완전한 보조 프로그램 저장하고 살펴보기
다음 문단에는 보조 프로그램 전체가 압축된 한 줄 패키지로 들어 있습니다. 문단 전체를 복사하여 작업 폴더의 unpack_rating_helper.py라는 일반 텍스트 파일에 붙여 넣으세요. 논리적으로 한 줄인 상태를 유지해야 하며, 편집기에서 화면 너비에 따라 줄이 접혀 보이는 것은 괜찮습니다. 따옴표, Markdown 코드 구분 기호, 앞뒤 기사 문장을 추가하지 마세요.
이 압축 해제 프로그램은 오프라인으로 작동합니다. 포함된 소스의 압축을 풀고 SHA-256을 검사한 뒤, 살펴볼 수 있도록 sync_jpeg_ratings.py를 새 파일로만 생성합니다. 보조 프로그램을 실행하지도, 무엇을 다운로드하지도 않습니다. 같은 이름의 파일이 이미 있으면 덮어쓰지 않고 중단합니다.
import base64,zlib,hashlib,sys; from pathlib import Path; data=zlib.decompress(base64.b64decode('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')); f=Path("sync_jpeg_ratings.py").open("xb") if hashlib.sha256(data).hexdigest()=='ba1136a7f667973bf1fef54682971bf964f4518825c99d45955ed871fdb88158' else sys.exit("SHA-256 mismatch; no helper file written"); f.write(data); f.close(); print("Created sync_jpeg_ratings.py for inspection; it has not been run.")
python3 unpack_rating_helper.py
사용하기 전에 생성된 sync_jpeg_ratings.py를 텍스트 편집기로 열어 보세요. 복원된 파일의 크기는 34,478바이트이며 SHA-256은 ba1136a7f667973bf1fef54682971bf964f4518825c99d45955ed871fdb88158입니다. 해시가 일치하지 않으면 보조 프로그램 파일은 생성되지 않습니다. 검사를 제거하지 말고 원래 문단을 다시 복사하세요.
읽을 수 있는 형태로 복원된 프로그램은 기존 RAW 사이드카 파일의 임시 사본에서 XMP-xmp:Rating만 변경합니다. RDFLib를 사용해 나머지 RDF 메타데이터를 모두 비교하므로, 의미가 같은 XML 표기 차이는 허용하지만 편집 데이터의 변경은 허용하지 않습니다. 이미지 픽셀을 쓰거나 darktable 데이터베이스에 접근하거나 JPEG의 전체 XMP 블록을 복사하지 않습니다.
6. 계획을 만들고 제안된 모든 파일 짝 검토하기
작은 날짜 폴더 하나나 선택한 연도 폴더 트리부터 시작하세요. 이 명령의 사진 경로와 ExifTool 경로를 자신의 경로로 바꾸세요. 기본 동작은 새 JSON 매니페스트를 기록하는 것이며, 모든 사진과 사이드카 파일은 그대로 둡니다.
python3 sync_jpeg_ratings.py "/path/to/Photos/2024" --rating-source sidecar --manifest "ratings-plan.json" --exiftool "/path/to/exiftool"
JPEG에 내장된 별점을 사용하려면 sidecar를 jpeg로 바꾸세요. 필요하다면 --jpeg-subdir "Jpgs" 또는 --raw-ext ARW에 적절한 값을 넣어 추가합니다. Windows에서는 다음과 같은 완전한 명령을 사용할 수 있습니다.
py -3 sync_jpeg_ratings.py "D:/Photos/2024" --rating-source sidecar --manifest "ratings-plan.json" --exiftool "C:/Tools/ExifTool/exiftool.exe"
ratings-plan.json을 여세요. counts부터 확인한 다음, 각 ready 행의 jpeg, raw, raw_sidecar, rating_source, target_rating, new_rating을 살펴보세요. 경로와 의도한 기존 값→새 값 변경, 내장 별점과 사이드카 별점의 불일치 경고를 모두 확인하세요. 미리 실행이 성공했다고 해서 모든 이미지가 준비되었다는 뜻은 아닙니다.
Ready로 분류된 짝은 적용 대상이 될 수 있습니다. Unchanged인 짝에는 원하는 값이 이미 들어 있습니다. Skipped인 짝은 선택한 출처에 명시적인 별점이 없습니다. Blocked인 짝은 확인이 필요하며, 사이드카 파일 누락, 알 수 없는 별점, 파일명 충돌, 편집 버전일 가능성, 그 밖의 지원하지 않는 조건 등이 사유로 표시됩니다. 원인을 해결한 뒤 새 매니페스트를 만드세요.
계획에는 파일 식별 정보, 수정 시간, 파일 전체 해시, 관련된 주변 파일명이 기록됩니다. RAW 픽셀을 수정하지 않더라도 큰 RAW 파일의 해시를 계산하는 데는 시간이 걸립니다. 다룰 만한 크기의 폴더 트리를 선택하세요. 계획이 비어 있다면 선택한 폴더에 조건에 맞는 Jpgs 하위 폴더가 없다는 뜻일 수 있습니다. 보관 자료 전체에 별점이 있는 JPEG가 없다는 증거는 아닙니다.
7. 별 0개, 거부 표시, 기존 별점을 구분하여 처리하기
출처 값으로 허용되는 범위는 -1부터 5까지의 정수입니다. 0은 실제 별 0개이고, -1은 실제 거부 표시입니다. 필드가 없다는 것은 이 두 값 중 어느 것도 아닙니다. 선택한 출처에 값이 없으면 보조 프로그램은 RAW의 별점을 보존합니다. 읽을 수 없거나, 소수이거나, 범위를 벗어나거나, 모호한 별점은 차단합니다.
기본적으로 유효한 출처 값은 대상 별점이 없거나 0일 때 기록될 수 있습니다. 같은 값이면 그대로 둡니다. 기존 값이 1–5 또는 -1이고 출처 값과 다르면 보호되며, 출처 값이 이를 0으로 지우려는 경우도 마찬가지입니다. darktable 문서에 명시된 가져오기 시 초기 별점의 기본값은 1이므로, 새로 가져온 RAW도 이 보호 규칙에 걸릴 수 있습니다.
의도한 전송을 위해 기존 값을 실제로 바꿔야 한다면 해당 짝들을 검토하고 --replace-rated를 넣어 별도의 계획을 만드세요. 이 설정은 새 계획 전체에서 적용 가능한 충돌에 작용합니다. 특정 행 하나만 선택하는 체크박스로 생각하지 말고, 적절히 작은 폴더 트리를 사용하세요.
python3 sync_jpeg_ratings.py "/path/to/Photos/2024" --rating-source sidecar --replace-rated --manifest "ratings-replace-plan.json" --exiftool "/path/to/exiftool"
새 매니페스트를 적용하기 전에 검토하세요. 작업을 강제로 실행하려고 JSON 값이나 상태를 직접 수정하지 마세요. 체크섬은 검토한 계획이 실수로 변경되는 것을 막으며, 적용 단계에서도 짝짓기, 출처, 충돌 정책, 현재 파일을 확인합니다. 교체 옵션을 사용해도 잘못된 별점이나 모호한 파일 짝이 허용되지는 않습니다.
8. 검토한 계획 적용하고 처리 기록 보관하기
darktable을 계속 닫아 둔 상태에서 검토했던 바로 그 매니페스트를 적용하세요. 새 교체 계획을 검토하여 사용하기로 했을 때만 여기에서 ratings-replace-plan.json을 사용합니다. ExifTool 경로는 앞서 사용한 것과 같게 유지하세요.
python3 sync_jpeg_ratings.py --apply "ratings-plan.json" --exiftool "/path/to/exiftool"
각 파일을 쓰기 전에 보조 프로그램은 선택한 별점을 다시 읽고, 계획에 기록된 파일과 디렉터리 목록을 검증합니다. 매니페스트 옆에 고유한 rating-sync-backup-<plan-id> 폴더를 만들고 원본 RAW 사이드카 파일을 저장합니다. 그 안의 sidecars 디렉터리에는 대상의 상대 폴더 경로가 유지됩니다. receipt.json에는 각 대상, 백업, 이전 별점과 새 별점, 해시가 기록됩니다.
ExifTool은 교체를 위해 준비한 사이드카 파일에서 전체 이름으로 지정된 별점 필드 하나를 변경합니다. 그다음 보조 프로그램이 별점과 별점을 제외한 전체 RDF 데이터를 확인하고, 입력 상태를 다시 검사한 뒤 해당 대상을 교체합니다. 실제로 반영된 사이드카 파일을 검증하고 RAW, JPEG, 그리고 기록된 JPEG 사이드카 파일이 있다면 그 파일까지 기존 지문과 일치하는지 확인합니다. XML 서식이나 툴킷 식별자는 달라질 수 있으며, 원래 바이트는 백업에 남아 있습니다.
파일이나 관련 파일명 목록이 바뀌었거나 매니페스트가 수정되었다면 더 이상 유효하지 않은 작업을 중단합니다. 일괄 처리 도중 오류가 나면 앞서 완료된 짝은 완료된 상태로 남고, 뒤의 짝은 시도하지 않은 상태로 남습니다. 처리 기록의 result_counts와 unattempted_ready_pairs를 확인하세요. 이것은 파일별 반영을 순서대로 수행하는 과정이며, 전체가 한 번에 성공하거나 모두 취소되는 일괄 작업이 아닙니다.
committed_verification_failed 또는 commit_state_requires_inspection을 주의해서 확인하세요. 이 상태는 현재 파일을 기록된 해시와 대조해야 한다는 뜻입니다. 교체 이후 발생한 오류가 아무것도 바뀌지 않았다는 뜻은 아닙니다. 작업이 중단되었다면 마지막으로 저장된 prepared 항목도 확인해야 합니다. 매니페스트, 처리 기록, 백업은 함께 보관하세요.
고유한 백업 디렉터리는 같은 계획을 무심코 두 번 실행하는 것을 막습니다. 중단된 일괄 처리의 문제를 해결한 뒤에는 남은 작업을 위한 새 계획을 만드세요. 이 보호 장치를 피하려고 이전 백업 디렉터리를 삭제하지 마세요. 처리 기록상 작업이 완료되었더라도 darktable_reload는 여전히 pending으로 남습니다.
9. 사이드카 파일을 darktable에 불러오고 결과 확인하기
darktable을 시작하세요. 갱신된 사이드카 파일 대화상자에서 대상 RAW 항목을 선택하고, XMP 내용을 데이터베이스에 불러오는 동작인 keep the XMP edit를 선택합니다. 오래된 데이터베이스 상태를 사이드카 파일에 다시 쓰는 keep the database edit는 선택하지 마세요. 이 버튼 이름은 현재 공식 소스에서 확인했으며, 버전과 번역에 따라 표현이 달라질 수 있습니다.
예상한 항목이 목록에 없더라도 전송이 실패했거나 성공했다고 단정하지 마세요. 시작 시 검사는 설정과 타임스탬프에 영향을 받습니다. 대안으로 lighttable의 import > add to library를 사용하세요. 원래 RAW 폴더로 이동한 뒤 select only new images의 체크를 해제하고, 이번 일괄 처리에 해당하는 기존 RAW 파일들을 명시적으로 선택합니다. 이 체크박스는 처음 선택되는 범위를 제어할 뿐이므로, 체크를 해제하는 것만으로 대상 파일을 선택한 것이 되지는 않습니다. 추가 작업을 완료하여 해당 파일의 XMP 데이터를 다시 불러오세요.
파일은 기존 위치에서 사용하세요. copy & import는 다른 가져오기 경로를 만들며 기존 사이드카 파일도 같은 방식으로 사용하지 않습니다. 이미지를 라이브러리에서 빼거나 삭제할 필요는 없습니다. refresh exif는 원본 이미지를 다시 읽어 별점을 덮어쓸 수 있고, JPEG 사이드카 파일을 RAW의 history stack으로 불러오면 편집 내용을 바꿔 버릴 수 있습니다. 이 동작들은 이번 전송에서 필요한 다시 읽기 단계가 아닙니다.
화면에 표시되는 RAW 별점, 거부 상태, 원래 편집 내용을 확인하세요. 사용 중인 사용자 지정 정렬 순서도 확인해야 합니다. 사용자 지정 정렬 위치는 XMP에 저장되지 않으므로, 사이드카 파일을 보존한다고 해서 데이터베이스에만 있는 모든 세부 상태까지 복원된다고 보장할 수는 없습니다. 그 상태가 중요하다면 데이터베이스 백업을 보관하세요.
추가로 편집하기 전에 확인된 전송 하나를 되돌리려면 darktable을 닫고, 처리 기록에서 정확한 raw_sidecar와 그에 대응하는 backup을 찾으세요. 백업을 backup_sha256과 대조하고 현재 사이드카 파일을 new_sidecar_sha256과 대조하세요. 다음 읽기 전용 명령은 파일의 SHA-256을 출력합니다. 각 실제 경로를 차례로 넣어 실행하세요.
python3 -c "import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())" "/full/path/to/sidecar.xmp"
현재 대상이 기록된 전송 결과 버전과 여전히 일치한다면 파일 관리자를 사용해 그 원본 백업 하나를 정확히 해당하는 RAW 사이드카 파일에 덮어쓰세요. 복원한 사이드카 파일을 darktable에 불러온 뒤 다시 확인합니다. 적용 이후 현재 파일이 바뀌었다면 무엇이든 복원하기 전에 그 파일을 별도로 보존하고 이후 편집 내용을 살펴보세요. 관계없는 대상은 건드리지 마세요. 현재 일괄 처리 범위의 별점과 편집 상태를 확인한 뒤에만 다음 날짜 폴더로 넘어가세요.
검증 범위: 제공된 보조 프로그램은 Python 3.12, RDFLib 7.6.0, 공급업체 배포본 13.59.3에 포함된 ExifTool 13.59를 사용한 완전한 CLI 테스트 27개를 통과했습니다. 테스트에는 생성한 JPEG, 편집 이력을 포함하도록 합성한 darktable 형식의 XMP, 그리고 RAW 내용을 해석하지 않고 변경 여부를 감시하는 대체 파일을 사용했습니다. 통제된 별점 변경, 이미지 바이트와 별점 외 메타데이터의 유지, 백업, 충돌, 오래된 입력 상태, 부분 완료, 의도적인 단일 대상 복원을 확인했습니다. 압축 해제 프로그램도 복원 테스트 4개를 통과했습니다. 해시 검사는 Python 최적화 모드에서도 작동하며, 기존 출력 파일을 덮어쓰지 않습니다. 이 결과에는 darktable GUI·데이터베이스 다시 읽기, 실제 카메라 RAW 디코딩, 여러 운영체제에서의 실행 검증은 포함되지 않습니다. UI 안내는 공식 5.6 매뉴얼과 현재 소스를 대조했습니다. 자신의 라이브러리에서 최종 결과를 확인하세요.