Files
sodalive-ios/docs/20260803_이미지_크롭_범위_보정/prd.md
2026-08-03 21:13:45 +09:00

5.2 KiB

이미지 크롭 범위 보정 PRD

문서 정보

항목 내용
문서 상태 구현 기준 확정
작성일 2026-08-03
최종 수정일 2026-08-03
대상 제품 SodaLive 이미지 선택 후 크롭 편집기
관련 구현 계획 docs/20260803_이미지_크롭_범위_보정/plan-task.md
관련 과거 기록 docs/plan-task/20260317_이미지등록크롭재구현.md, docs/plan-task/20260317_이미지선택크롭지연및미적용수정.md

1. Overview

이미지를 선택한 뒤 표시되는 공통 ImageCropEditorView가 crop 비율에 맞는 원본 최대 범위를 사용하도록 보정한다. 외부 cropper 의존성은 추가하지 않고 현재 편집 흐름과 서버 전송 규격을 유지한다.

2. Problem Statement

  • 고정 1:1 crop 영역은 canvas 최소 변의 72%로 계산되어 원본 표시 영역보다 불필요하게 작을 수 있다.
  • 자유 crop 영역의 초기 크기와 최대 크기도 canvas 기준이라 원본 표시 영역과 일치하지 않는다.
  • 따라서 crop 비율에 따라 원본의 가로 또는 세로 한 축 전체를 포함할 수 있어도 더 작은 영역만 잘린다.

문제 해결 여부는 세로·가로 이미지에서 현재 crop 비율을 유지하는 최대 사각형이 원본 표시 영역의 가로 또는 세로 한 축과 일치하는지로 판정한다.

3. Goals

  • 어떤 crop 비율에서도 원본 표시 영역 안에 들어가는 최대 crop 사각형을 계산한다.
  • 세로 이미지는 가능한 경우 표시된 이미지의 전체 가로를, 가로 이미지는 전체 세로를 crop 영역에 포함한다.
  • 자유 crop은 최대 범위를 fitted image 기준으로 제한하면서 기존 모서리 resize 동작을 유지한다.
  • 최종 crop 결과의 긴 변 최대 800px 정책과 기존 서버 multipart 경로를 유지한다.

4. Non-Goals

  • 외부 cropper 라이브러리 추가 또는 기존 편집기 교체
  • 새로운 crop 비율 선택 UI 추가
  • 이미지 선택 화면, 업로드 API, multipart 필드 변경
  • 회전, 반전, 원근 보정 기능 추가

5. 핵심 사용자 흐름

  1. 사용자가 기존 화면에서 이미지를 선택한다.
  2. 앱이 이미지를 정규화하고 ImageCropEditorView를 표시한다.
  3. 편집기는 현재 crop 비율에 맞는 최대 영역을 fitted image 안에서 계산한다.
  4. 사용자가 이동·확대 또는 자유 crop resize 후 적용한다.
  5. 앱은 기존처럼 crop 결과를 긴 변 최대 800px로 축소해 각 ViewModel의 기존 업로드 경로로 전달한다.

6. 기능 요구사항

ID 상태 요구사항 수용 기준
CROP-001 확정 crop 비율을 유지하는 최대 크기를 fitted image 안에서 계산한다. 반환 rect의 가로 또는 세로가 fitted image의 같은 축과 일치하고 두 축 모두 경계를 넘지 않는다.
CROP-002 확정 고정 1:1 crop에 최대 범위 계산을 적용한다. 세로 이미지는 전체 가로, 가로 이미지는 전체 세로를 초기 crop 영역으로 사용한다.
CROP-003 확정 자유 crop의 초기 영역과 resize 상한을 fitted image 기준으로 계산한다. 초기 영역은 현재 기본 비율의 최대 크기이며 모서리 resize 결과가 fitted image 크기를 넘지 않는다.
CROP-004 확정 최종 전송 이미지 크기 정책을 유지한다. cropImage()가 계속 resizedToMaxDimension(800) 결과를 반환한다.
CROP-005 확정 기존 호출부 계약을 유지한다. ImageCropAspectPolicy, onCancel, onComplete(UIImage)와 5개 호출부 수정이 없다.

7. 기술 제약

  • iOS 16.6 이상, SwiftUI와 UIKit을 유지한다.
  • geometry 계산은 UI와 분리된 순수 함수로 두어 독립 실행 검증이 가능해야 한다.
  • 테스트 번들 타깃이 없는 현재 저장소 구조에서는 swiftc로 순수 geometry check를 실행한다.
  • Pods/**, generated/**, 업로드 API는 수정하지 않는다.

8. 성공 기준

  • 세로 fitted image 350x700, 비율 1:1에서 crop 크기가 350x350이다.
  • 가로 fitted image 400x200, 비율 4:3에서 crop 크기가 약 266.67x200이다.
  • fitted image와 crop 비율이 같으면 전체 fitted image 크기를 반환한다.
  • 0 이하 크기 또는 비율은 .zero를 반환한다.
  • 자유 crop resize 상한이 fitted image를 넘지 않는다.
  • 앱 빌드가 성공하고 최종 crop 결과의 긴 변 최대 800px 정책이 유지된다.

9. Open Questions

해당 없음.

10. Decision Log

날짜 ID 상태 결정 근거 영향 요구사항
2026-08-03 DEC-001 확정 외부 라이브러리 대신 기존 cropper geometry를 보정한다. 현재 문제는 공통 cropSize와 fitted image 경계 계산에서 발생하며 한 컴포넌트에서 해결 가능하다. CROP-001~005
2026-08-03 DEC-002 확정 1:1은 예시이며 모든 crop 비율에 최대 fitted 영역 규칙을 적용한다. 사용자 확인 CROP-001~003
2026-08-03 DEC-003 확정 최종 이미지 긴 변 최대 800px 정책을 유지한다. 서버 전송 크기를 기존과 동일하게 유지한다는 사용자 확인 CROP-004