Files
photoai/docs/DARKTABLE_REVIEW.md
T
koriweb 3e73967c7b darktable-inspired reskin + metadata/collections, map, easy mode, select/export
UI overhaul to a darktable tone-and-manner and a set of features adapted from
darktable's proven patterns (reimplemented in our Electron/TS stack; no GPL code).

Design reskin:
- Dark neutral-gray palette + amber accent, flat/squared corners, no card shadows,
  compact darktable-style top bar (logo + pipe-separated view tabs), denser 15px base
- Done via design tokens (Tailwind slate/brand/radius/shadow remap) — minimal churn

Metadata & collections (Phase A/B):
- exifr now captures GPS + camera; asset table ALTER-migrated (gpsLat/gpsLon/camera,
  metaVersion backfill on re-index)
- Collection facet bar (year timeline / camera / color-label) filters the grid

Map & relation finder (Phase C):
- Leaflet + online OSM map tab; geotagged photos as markers
- relationService: related photos by place (GPS<1km) + time (+/-2d) + CLIP similarity

Easy mode (Phase D):
- easyMode setting (menu / onboarding); scales the whole UI (rem) + bigger thumbnails
  + large icon nav with plain labels (4050 accessibility)

Library usability:
- Video thumbnails (representative frame capture in the inference worker)
- Media filter (All / Photos / Videos) to separate them
- Clearer culling labels ("Good shots" / "To cull") + explanation tooltip
- Multi-select tiles -> Export selected to a folder (copy, best-cut extraction) and
  Delete to Recycle Bin (shell.trashItem) behind a confirm dialog
- ONNX Runtime wasm bundled locally (offline) via copy-ort-wasm + asarUnpack

Docs: DARKTABLE_REVIEW (feasibility + roadmap A->D). All typecheck/tests/build green;
boot smoke verified each phase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 19:22:19 +09:00

108 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# darktable 차용 검토 & 메타데이터/탐색 기능 로드맵
> 상태: 검토/계획 초안 · 2026-06-01
> 대상: darktable 5.4.1 소스(C/GTK/Lua) 참고 + PhotoAI 기획서("메타데이터 기반 자동 분류/연관 탐색")
> 베이스: 현재 PhotoAI (Electron + React/TS, 인덱스 DB + 얼굴/CLIP/컬링)
---
## 0. 먼저, 솔직한 핵심 정정 2가지
**(1) "darktable 엔진을 가져다 쓴다"는 건 사실상 불가합니다 — 하지만 안 가져와도 됩니다.**
- darktable은 **C/GTK/Lua** 데스크톱 앱입니다. 우리는 **Electron/TypeScript**라 darktable의 코드/엔진을 in-process로 링크할 수 없습니다.
- darktable을 끌어오는 유일한 방법은 (a) 바이너리 동봉 후 CLI 호출(`darktable-cli`) 또는 (b) 같은 하위 라이브러리(`exiv2`) 사용인데, **둘 다 GPL3 전염 + 무거운 네이티브 의존**(우리가 better-sqlite3에서 겪은 빌드 지옥)을 유발합니다. 권장하지 않습니다.
- **좋은 소식**: darktable이 메타데이터에 쓰는 기능 대부분을, 우리는 **이미 설치된 `exifr`로 그대로 얻습니다.** exifr는 EXIF뿐 아니라 **GPS(위도/경도), IPTC, 카메라/렌즈** 까지 파싱합니다. 즉 "메타데이터 추출 엔진"은 **darktable 없이 이미 확보**되어 있습니다.
→ 결론: **darktable의 코드가 아니라 "검증된 UX 패턴과 데이터 모델"을 차용**하고, 추출은 exifr로 우리 스택에서 재구현합니다. (GPL/네이티브 회피)
**(2) 기획서의 "자녀별 자동 분류(시나리오 A)"는 이미 상당 부분 구현되어 있습니다.**
- 우리 **정리(Organize) 탭 = 얼굴 인식으로 인물(자녀)별 + 날짜별 폴더 자동 분류**. 이게 정확히 시나리오 A입니다. "AI 태깅"을 새로 만들 필요 없이 기존 얼굴 매칭이 그 역할을 합니다.
- 따라서 이번 단계의 **진짜 새 가치는 "장소(GPS) 기반 탐색"과 "탐색 UX(필터 트리/타임라인/지도)", "4050 쉬운 모드"** 입니다.
---
## 1. darktable에서 가져올 만한 것 (모듈 매핑)
| darktable 소스 | 개념 | 우리 차용 방식 | 가치 |
|----------------|------|----------------|------|
| `views/lighttable.c` | 그리드 + 필름스트립 + 별점/색라벨 + 줌 | **이미 보유**(라이브러리 그리드/별점/색라벨). 필름스트립/줌은 보강 여지 | 중 |
| `libs/collect.c` | 좌측 **컬렉션 필터 트리**(폴더/날짜/카메라/태그/색라벨/평점/**GPS 위치**) | 우리 인덱스 DB로 **필터 트리 패널** 재구현 | **높음** |
| lighttable 하단 | **타임라인**(연/월 빠른 이동) | 인덱스의 exifYear/Month로 타임라인 바 | **높음** |
| `views/map.c` + `libs/geotagging.c` | **GPS 지도 뷰** + 지오태깅 | Leaflet(JS) + OSM 타일로 지도/클러스터 재구현 | **높음(신규)** |
| `libs/metadata.c` / `metadata_view.c` | 메타데이터 표시 + **XMP 사이드카** | 메타 패널은 재구현. XMP는 **선택적 내보내기**(상호운용) | 중 |
| `libs/tagging.c` | 태그 | 향후(현재 별점/색라벨로 일부 대체) | 낮음 |
| `views/darkroom.c` | RAW 편집 | **비목표(기획서 동의)** — 복잡도의 근원, 제외 | - |
---
## 2. 우리 현황 ↔ 기획서 매핑
| 기획서 항목 | 현재 상태 | 필요 작업 |
|-------------|----------|-----------|
| 자녀별 자동 분류(시나리오 A) | ✅ **구현됨**(정리 탭, 얼굴+날짜) | (유지) |
| 메타데이터 추출(EXIF) | ✅ 부분(촬영일) | **GPS/IPTC/카메라 추가**(exifr, 쉬움) |
| 썸네일 캐싱/프리뷰 | ✅ 구현됨(canvas→webp) | (유지) |
| 컬렉션 필터 트리(인물/연/도시) | ❌ | **신규** — 인덱스 기반 트리 패널 |
| 타임라인 | ❌ | **신규** — 연/월 스크롤 바 |
| 장소/여행지 탐색(시나리오 B) | ❌ | **신규** — GPS 지도 + 연관 탐색 |
| Relation Finder(동일 GPS/시간) | ❌ | **신규** — GPS+시간(+인물) 연관 그룹 |
| 4050 쉬운 모드(대형 버튼/구어체) | ❌ | **신규** — 접근성 UI 모드 |
| XMP 사이드카 | ⚠️ 우리 SQLite 인덱스가 대체 | **선택** — 내보내기로 상호운용 |
| 사용성(구어체 레이블) | ⚠️ 일부 | 쉬운 모드와 함께 |
---
## 3. 기획서 평가 + 정정 제안
- 👍 방향성(메타데이터 기반 분류 + 연관 탐색 + 단순 UX)은 우리 자산과 잘 맞습니다.
- ✏️ **정정 1**: "darktable 엔진 확보"는 exifr로 대체(§0-1). 기술 리스크/라이선스 회피.
- ✏️ **정정 2**: "AI 태깅으로 자녀 분류"는 이미 있는 **얼굴 인식**으로 충족(§0-2). 중복 개발 불필요.
- **추가 제안**: 연관 탐색을 GPS만이 아니라 **GPS + 시간 + 인물(얼굴) + 시각유사도(CLIP)** 를 결합하면 darktable보다 강력합니다(darktable엔 얼굴/의미검색이 없음). "이 사진과 관련된 사진" = 같은 장소·시기·인물·비슷한 장면.
- **추가 제안**: "쉬운 모드"는 별도 앱이 아니라 **기존 UI에 토글되는 접근성 레이아웃**으로 — 유지보수 1벌.
---
## 4. 리파인된 로드맵 (제안)
- **Phase A — 풍부한 메타데이터 캡처** *(선행, 저비용)*
인덱서의 exifr 호출을 확장해 **GPS(위/경도) · 카메라/렌즈 · IPTC**를 인덱스 DB에 저장. (지도/필터 트리의 데이터 토대)
- **Phase B — 컬렉션 필터 트리 + 타임라인** *(탐색 UX 핵심)*
좌측 패널: **인물 / 연도 / 도시(역지오코딩) / 카메라**로 즉시 필터. 하단 **타임라인**으로 연·월 점프. (darktable collect.c + lighttable 타임라인)
- **Phase C — 지도(Place) 뷰 + Relation Finder** *(시나리오 B)*
GPS 좌표를 지도에 클러스터로 표시. 사진 클릭 → **연관 사진**(같은 장소·시기·인물·유사장면) 패널. (darktable map.c를 우리식으로)
- **Phase D — 4050 쉬운 모드(접근성)** *(차별화 UX)*
대형 버튼·큰 썸네일·구어체 레이블("언제 찍었나요?/어디인가요?")의 **토글형 간편 레이아웃**. (기획서 "리모컨 UI")
- **(선택) XMP 사이드카 내보내기** — Lightroom/darktable 상호운용.
> 권장 1순위: **Phase A + B**(데이터 + 탐색 UX). 우리가 이미 색인한 자산이 즉시 "탐색 가능한 라이브러리"가 됩니다. GPS 지도(C)는 그 다음, 쉬운 모드(D)는 UX 마감.
---
## 5. 결정 — 확정(2026-06-01)
- **진행**: **A+B 먼저**(메타데이터 + 컬렉션 트리/타임라인). 이후 C(지도) → D(쉬운 모드).
- **지도 타일(Phase C)**: **온라인 OSM**.
- 비고: 라이브러리 그리드의 **인물(자녀)별 필터**는 인덱스에 얼굴-프로필 매칭을 저장하는 후속 작업(B.2)으로 둠. A+B는 연도/카메라/평점/색라벨/타임라인 우선.
## 5-1. 구현 현황
- [x] **Phase A 완료(2026-06-01)**: exifr로 **GPS(위/경도) + 카메라 모델** 추출(`readMeta`), `asset` 테이블에 `gpsLat/gpsLon/camera` 컬럼 + 기존 DB **ALTER 마이그레이션**. `metaVersion`으로 구버전 행은 재색인 시 **GPS/카메라 backfill**(기존 썸네일 재사용 → 저비용). 부팅 시 110-asset DB 마이그레이션 무오류 확인.
- [x] **Phase B 완료(2026-06-01)**: `indexDb.facets`(연도/카메라/색라벨 집계) + `AssetQuery` 확장(year/camera/label) + 라이브러리 그리드에 **컬렉션 패싯 바**(연도 타임라인 · 카메라 칩 · 색라벨, 카운트 포함) 추가. 필터는 즉시 그리드에 반영.
- 비고: **인물(자녀)별 필터**(B.2)와 **월 단위 타임라인**, **쉬운모드(D)**는 후속. 기존 사진의 GPS/카메라는 **재색인 1회**로 채워짐.
- [x] **Phase C 완료(2026-06-01)**: **Leaflet + 온라인 OSM 타일** 지도 탭 — GPS 사진을 마커로 표시(클릭 시 썸네일 팝업). **연관 탐색(Relation Finder)**: `relationService`**장소(GPS 1km 이내) + 시간(±2일) + 시각유사도(CLIP)** 를 결합해 "이 사진과 관련된 사진"을 랭킹(darktable의 GPS 연관에 인물/의미까지 확장). CSP에 OSM 타일 도메인 허용. typecheck/build/부팅 스모크 통과.
- [x] **Windows 설치파일 빌드**: `AI Photo Organizer-0.1.0-win-x64.exe`(190MB, ORT wasm/모델 동봉, asar 언팩 검증).
- [x] **Phase D 완료(2026-06-01)**: **4050 쉬운 모드**`easyMode` 설정(영속화) 토글(메뉴 보기 · 온보딩). 켜면 `<html class="easy">`로 ① rem 기준 **전체 UI 확대**(16→20px) ② **썸네일 그리드 3열로 큼직** ③ 상단이 **대형 아이콘+구어체 버튼**(사진 정리/내 사진/사진 찾기/지도/중복 정리). 기존 UI를 토글 1벌로 재사용(유지보수 단순). typecheck/build/부팅 스모크 통과.
## 7-1. 최종 구현 현황 (요약)
탭 5개: **정리 / 라이브러리 / 검색 / 지도 / 그룹·정화** + **쉬운 모드** 토글.
- 정리: 얼굴+날짜 자동 분류(시나리오 A) · 라이브러리: 색인/썸네일/컬링/별점·색라벨/컬렉션 필터(연도·카메라)
- 검색: CLIP 자연어(한국어 번역) · 지도: GPS+연관탐색(시나리오 B) · 그룹·정화: 근접중복+휴지통
- 남은 후속: 인물(자녀)별 필터(B.2) · 월 타임라인 · 역지오코딩(도시명) · 가족 공유(미래)
## 6. (구) 결정이 필요했던 사항
1. **지도 타일 소스**: 온라인 OSM 타일(간단, 인터넷 필요) vs 오프라인 타일 동봉(용량 큼). → 온라인 권장(로컬-퍼스트지만 지도는 예외적으로 온라인 허용).
2. **역지오코딩(좌표→도시명)**: 온라인 API(Nominatim 등, 쿼터/인터넷) vs 좌표만 표시. → v1은 좌표/지도 우선, 도시명은 후속.
3. **쉬운 모드 범위**: 별도 단순 화면 1개 vs 전체 탭의 대형화 토글.
4. **진행 우선순위**: A+B 먼저 / 지도(C) 우선 / 쉬운 모드(D) 우선 / 전부.