Skip to content

인증샷 샘플링 로직 추가#120

Open
chanho0908 wants to merge 1 commit intodevelopfrom
feat/#119-photolog-upload-modifiy
Open

인증샷 샘플링 로직 추가#120
chanho0908 wants to merge 1 commit intodevelopfrom
feat/#119-photolog-upload-modifiy

Conversation

@chanho0908
Copy link
Member

@chanho0908 chanho0908 commented Mar 3, 2026

이슈 번호

#119

작업내용

기존에 인증샷 업로드시 너무 시간이 오래걸리는 문제를 해결하기 위해 작업했어 😵‍💫

🥊 문제 상황

갤럭시 S25 기준 촬영 이미지 해상도는 4080x3060 이며 이를 원본 그대로 presigned URL을 통해 업로드하면서 최대 2.6초까지 소요되는 현상을 확인했어

📝 원인 분석

PresignedUploader에 로깅을 추가해 계측한 결과 다음 결과가 나왔어

  • 평균 파일 크기: 약 2.8MB
  • 업로드 시간: 약 1.8 ~ 2.6초

이를 통해 고해상도 이미지를 리사이징 없이 그대로 업로드하면서 네트워크 전송 구간에서 병목이 발생하고 있음을 확인했어

🛎️ 개선 내용

  1. 이미지를 바로 Bitmap으로 디코딩하는 대신 BitmapFactory.Options(inJustDecodeBounds = true) 를 사용해
    실제 디코딩 없이 이미지 크기만 먼저 측정
  2. calculateInSampleSize() 로 목표 해상도(FHD 기준)에 맞는 샘플링 비율 계산
  3. 다운샘플링 후 JPEG 재압축

이번 작업을 진행하면서 공부한 내용을 블로그에 정리해봤어

결과물

PresignedUploader에 로그를 통해서 업로드에 걸리는 시간을 측정한 결과야 !

Before After
image image

리뷰어에게 추가로 요구하는 사항 (선택)

샘플링 기준을 FHD 기준으로 잡았는는데 혹시 의견 있다면 편하게 말해줘 !
image

@chanho0908 chanho0908 self-assigned this Mar 3, 2026
@chanho0908 chanho0908 added the Refactor Good for newcomers label Mar 3, 2026
@chanho0908 chanho0908 linked an issue Mar 3, 2026 that may be closed by this pull request
1 task
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

ImageGenerator.kt에서 이미지 처리 기능을 개선했습니다. 메모리 효율성을 높이기 위해 BitmapFactory의 inJustDecodeBounds를 활용한 두 단계 디코딩을 구현하고, calculateInSampleSize 헬퍼 함수로 최적의 샘플링 크기를 계산합니다. EXIF 메타데이터를 읽어 이미지 회전을 감지하고 디코딩 후 적용하는 기능을 추가했으며, 회전으로 생성된 새로운 비트맵에 대해 원본 비트맵을 회수합니다. 또한 calculateInSampleSize를 public 메서드로 노출하고 ImageProcessException으로 압축 실패를 처리하는 예외 처리를 확장했습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

상세 리뷰

긍정적인 부분

메모리 최적화와 리소스 관리 개선을 훌륭하게 구현하셨습니다. 특히 다음 부분들이 좋습니다:

  • 두 단계 디코딩 전략: inJustDecodeBounds를 먼저 사용하여 전체 이미지를 메모리에 로드하지 않고 크기 정보를 얻는 방식은 성능과 메모리 효율 측면에서 표준적인 모범 사례입니다.
  • 리소스 회수 구현: 회전으로 인해 새 비트맵을 생성할 때 원본을 recycling하는 코드는 메모리 누수 방지에 매우 효과적입니다.
  • 새로운 유틸리티 함수 노출: calculateInSampleSize를 public으로 제공하여 재사용성을 높인 설계가 좋습니다.

검토 권장사항

다음 사항들을 더 확인해보시기 바랍니다:

  1. 회전 처리 로직의 안정성: 회전 적용 후 original 비트맵을 recycling하는 부분에서, recycled 비트맵이 예상치 못한 곳에서 참조되지 않는지 확인이 필요합니다. 회전된 비트맵만 반환되는지 검증하셨나요?

  2. EXIF 회전 정보 신뢰성: 모든 이미지 포맷(PNG, WebP 등)에서 EXIF 메타데이터가 안정적으로 읽히나요? 메타데이터가 없는 경우의 fallback 처리가 충분한지 확인 부탁드립니다.

  3. calculateInSampleSize 입력값 검증: reqWidth와 reqHeight가 음수이거나 0인 경우에 대한 입력값 검증이 있으신가요? 이는 사용자가 잘못된 값을 전달할 때 예상 불가능한 동작을 방지합니다.

  4. 예외 처리 문서화: ImageProcessException.CompressionFailedException을 throw하도록 개선하셨는데, KDoc에서 어떤 상황에 이 예외가 발생하는지 명확히 기술하면 호출부에서의 처리가 더 용이할 것 같습니다.

  5. 메모리 누수 검증: 여러 회전 케이스(0, 90, 180, 270도)에 대해 비트맵이 정확히 한 번만 recycling되는지 단위 테스트로 검증하시길 권장합니다.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 핵심 개선사항인 이미지 샘플링 로직 추가를 명확하게 요약하고 있으며 변경사항과 완전히 관련이 있습니다.
Description check ✅ Passed PR 설명은 성능 문제의 원인, 개선 방법, 측정 결과를 상세히 제시하며 변경사항과 완전히 관련이 있습니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#119-photolog-upload-modifiy

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
core/ui/src/main/java/com/twix/ui/image/ImageGenerator.kt (1)

66-69: 타겟 해상도(1920x1080) 하드코딩에 대한 제안

현재 FHD(1920x1080)가 하드코딩되어 있습니다. PR 설명에서 리뷰어에게 이 기준에 대한 의견을 요청하셨는데, FHD는 대부분의 모바일 화면에서 충분한 해상도이므로 합리적인 선택으로 보입니다.

다만, 향후 유지보수성을 위해 상수로 추출하는 것은 어떨까요?

♻️ 상수 추출 제안
 companion object {
     private const val IMAGE_COMPRESSION_ERROR_MESSAGE = "Config: %s, Size: %dx%d"
+    private const val TARGET_WIDTH = 1920
+    private const val TARGET_HEIGHT = 1080
 }

그리고 사용처에서:

-            inSampleSize = calculateInSampleSize(bounds, 1920, 1080)
+            inSampleSize = calculateInSampleSize(bounds, TARGET_WIDTH, TARGET_HEIGHT)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/ui/src/main/java/com/twix/ui/image/ImageGenerator.kt` around lines 66 -
69, The code in ImageGenerator.kt hardcodes the 1920x1080 target resolution when
creating BitmapFactory.Options (inSampleSize = calculateInSampleSize(bounds,
1920, 1080)); extract these magic numbers into named constants (e.g.,
TARGET_WIDTH and TARGET_HEIGHT) either as top-level constants or in a companion
object of ImageGenerator, replace the literals in the calculateInSampleSize call
with those constants, and update any related usages/comments to reference the
new constants so the target resolution is configurable and easier to maintain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/ui/src/main/java/com/twix/ui/image/ImageGenerator.kt`:
- Around line 60-74: In uriToBitmap, validate the first-pass bounds before
calling calculateInSampleSize: after the inJustDecodeBounds decode, check
bounds.outWidth and bounds.outHeight for <= 0 (or -1) and if invalid throw
ImageProcessException.DecodeFailedException(imageUri) so you don't proceed with
a bogus inSampleSize; then continue to create the real BitmapFactory.Options and
call calculateInSampleSize only when bounds are valid (reference symbols:
uriToBitmap, bounds.outWidth, bounds.outHeight, calculateInSampleSize,
ImageProcessException.DecodeFailedException).

---

Nitpick comments:
In `@core/ui/src/main/java/com/twix/ui/image/ImageGenerator.kt`:
- Around line 66-69: The code in ImageGenerator.kt hardcodes the 1920x1080
target resolution when creating BitmapFactory.Options (inSampleSize =
calculateInSampleSize(bounds, 1920, 1080)); extract these magic numbers into
named constants (e.g., TARGET_WIDTH and TARGET_HEIGHT) either as top-level
constants or in a companion object of ImageGenerator, replace the literals in
the calculateInSampleSize call with those constants, and update any related
usages/comments to reference the new constants so the target resolution is
configurable and easier to maintain.

ℹ️ Review info

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db90af9 and 0b1107d.

📒 Files selected for processing (1)
  • core/ui/src/main/java/com/twix/ui/image/ImageGenerator.kt

@chanho0908 chanho0908 requested a review from dogmania March 3, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

인증샷 업로드 지연 문제 개선

1 participant