-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
📝 Issue Description
기존 OpenAI LLM 기반 홍보물 콘텐츠 생성(SpringAIPromotionProvider)에 HTML 폰트-이미지 합성 기능을 추가하여, 텍스트가 오버레이된 완성형 홍보물 이미지를 자동 생성하는 기능을 구현합니다.
🎯 Goals
- LLM 생성 콘텐츠를 기반으로 HTML 템플릿 생성
- 투명 배경 텍스트 이미지 생성 (Playwright 사용)
- 배경 이미지 다운로드 및 전처리
- 텍스트 오버레이 합성으로 최종 썸네일 PNG 생성
- 성능 최적화 (브라우저 인스턴스 재사용, 비동기 처리)
🔧 Technical Requirements
Environment
- Java 21
- Gradle
- Spring Boot 3.x
- Spring AI (OpenAI integration)
Dependencies to Add
dependencies {
// Playwright for HTML to PNG conversion
implementation 'com.microsoft.playwright:playwright:1.40.0'
// WebFlux for async image download
implementation 'org.springframework.boot:spring-boot-starter-webflux'
// Image processing utilities
implementation 'org.apache.commons:commons-imaging:1.0.0-alpha5'
// Async processing
implementation 'org.springframework.boot:spring-boot-starter-web'
}📋 Implementation Tasks
Phase 1: Core Infrastructure
-
Task 1.1:
PromotionImageService구현- 메인 홍보물 생성 메서드
- HTML 템플릿 → PNG 변환
- 이미지 합성 로직
-
Task 1.2:
ImageDownloadService구현- URL에서 이미지 다운로드 (WebClient 사용)
- 이미지 크기 조정 및 최적화
- 캐싱 메커니즘
-
Task 1.3:
HtmlTemplateService구현PromotionResult→ HTML 템플릿 변환- 반응형 CSS 스타일링
- 한글 폰트 지원 (Noto Sans KR)
Phase 2: Browser Management
-
Task 2.1:
PlaywrightBrowserPool구현- 브라우저 인스턴스 풀링
- 동시 접근 제어 (Semaphore)
- 리소스 정리 및 관리
-
Task 2.2: 투명 배경 텍스트 이미지 생성
- Headless 브라우저 설정
setOmitBackground(true)적용- 폰트 로딩 최적화
Phase 3: Integration & Enhancement
-
Task 3.1:
SpringAIPromotionProvider확장- 기존 LLM 호출 후 이미지 생성 추가
PromotionImageResult응답 구조 정의- 에러 처리 및 폴백 전략
-
Task 3.2: 비동기 처리 구현
@Async기반 백그라운드 처리- 진행 상태 추적 (
taskId기반) CompletableFuture활용
Phase 4: Performance & Monitoring
-
Task 4.1: 성능 최적화
- 브라우저 인스턴스 재사용
- 이미지 다운로드 캐싱
- 메모리 효율적 처리
-
Task 4.2: 모니터링 및 로깅
- 생성 시간 측정 (Micrometer)
- 메모리 사용량 추적
- 실패율 모니터링
📐 HTML Template Design
Layout Types
public enum PromotionLayoutType {
OVERLAY_CENTER, // 중앙 텍스트 오버레이
OVERLAY_BOTTOM, // 하단 정보 배치
SPLIT_LAYOUT, // 좌우 분할 레이아웃
CARD_STYLE // 카드형 디자인
}Template Structure
<div class="promotion-container">
<div class="spot-name">{{ spotName }}</div>
<div class="title">{{ suggestedTitle }}</div>
<div class="tags">
<span class="tag">{{ recommendedTag }}</span>
</div>
<div class="emotions">{{ emotions }}</div>
</div>⚙️ Configuration
application.yml
thumbnail:
image:
default-width: 1200
default-height: 630 # SNS 최적 비율 (1.91:1)
max-file-size: 5MB
quality: 85
timeout: 30s
template:
font-family: "Noto Sans KR"
primary-color: "#FFFFFF"
shadow-color: "rgba(0,0,0,0.8)"
browser:
pool-size: 3
headless: true
timeout: 10s🔄 Data Flow
PromotionRequest
↓
OpenAI LLM → PromotionResult
↓
mainImageUrl → Download Background Image
↓
PromotionResult → HTML Template
↓
HTML → Playwright → Transparent Text PNG
↓
Background + Text → BufferedImage Composite
↓
Final Thumbnail PNG
📊 Expected Performance
Target Metrics
- 전체 프로세스: 3-6초 (최적화 후)
- LLM 응답: 2-5초 (기존)
- 이미지 다운로드: 0.5-2초
- HTML → PNG 변환: 1-2초
- 이미지 합성: 0.2-0.5초
Performance Optimizations
- 브라우저 인스턴스 재사용으로 초기화 시간 단축
- 이미지 다운로드 캐싱
- 비동기 처리로 사용자 응답성 향상
🧪 Testing Strategy
Unit Tests
- HTML 템플릿 생성 검증
- 이미지 다운로드 테스트
- 합성 결과 이미지 검증
- 에러 상황 처리 테스트
Integration Tests
- End-to-End 썸네일 생성 플로우
- 다양한
PromotionResult입력 시나리오 - 성능 및 메모리 사용량 테스트
Test Data
// 테스트용 PromotionResult 샘플
PromotionResult testData = new PromotionResult(
"맛있는 카페",
"https://example.com/image.jpg",
List.of("커피", "디저트", "분위기"),
List.of("따뜻함", "아늑함"),
"감성 가득한 동네 카페에서의 특별한 시간",
"직접 로스팅한 원두로 내린 커피가 일품입니다. 아늑한 인테리어와 친절한 사장님이 기억에 남아요. 디저트도 맛있어서 재방문 의사 100%입니다."
);🚨 Error Handling & Fallback
Fallback Strategy
- LLM 실패: 기존
createFallbackPromotion()사용 - 이미지 다운로드 실패: 기본 배경 이미지 적용
- HTML 렌더링 실패: 텍스트만으로 간단한 이미지 생성
- 합성 실패: 원본 배경 이미지 반환
Error Monitoring
- 각 단계별 실패율 추적
- 실패 원인별 분류 및 로깅
- 알림 및 모니터링 대시보드 연동
🔍 Definition of Done
- 모든 구현 태스크 완료
- 단위 테스트 및 통합 테스트 통과 (커버리지 80% 이상)
- 성능 목표 달성 (3-6초 이내)
- 에러 처리 및 폴백 전략 구현
- 코드 리뷰 완료
- 문서화 완료 (API 문서, 설정 가이드)
📚 References
- [Playwright Java Documentation](https://playwright.dev/java/)
- [Spring WebFlux Reference](https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html)
- [BufferedImage Tutorial](https://docs.oracle.com/javase/tutorial/2d/images/)
Estimated Timeline: 2-3 weeks
Priority: High
Labels: enhancement, feature, backend, image-processing
Metadata
Metadata
Assignees
Labels
No labels