fix:슬라이드 폰트 크기 2배 확대 + 좌표 정확도 개선
- SlideAnnotationService: 아웃트로 메인텍스트 36→72, 서브텍스트 24→48 - ScreenAnalysisService: 그리드 오버레이 레터박스 제거 (전체 채움) → Gemini 좌표가 이미지 비율과 직접 매핑되어 스포트라이트 위치 정확도 향상 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,8 @@ class SlideAnnotationService
|
||||
{
|
||||
private const TARGET_WIDTH = 1920;
|
||||
private const TARGET_HEIGHT = 1080;
|
||||
private const CAPTION_HEIGHT = 100;
|
||||
private const MARKER_RADIUS = 20;
|
||||
private const CAPTION_HEIGHT = 180;
|
||||
private const MARKER_RADIUS = 35;
|
||||
|
||||
private string $fontPath;
|
||||
|
||||
@@ -166,25 +166,23 @@ private function drawCaptionBar(\GdImage $canvas, string $caption, int $stepNumb
|
||||
|
||||
// 상단 구분선 (인디고)
|
||||
$accent = imagecolorallocate($canvas, 79, 70, 229);
|
||||
imagefilledrectangle($canvas, 0, $barY, self::TARGET_WIDTH, $barY + 3, $accent);
|
||||
imagefilledrectangle($canvas, 0, $barY, self::TARGET_WIDTH, $barY + 4, $accent);
|
||||
|
||||
// 캡션 텍스트
|
||||
$white = imagecolorallocate($canvas, 255, 255, 255);
|
||||
$fontSize = 20;
|
||||
$textY = $barY + 55;
|
||||
$fontSize = 38;
|
||||
|
||||
if (file_exists($this->fontPath)) {
|
||||
// 텍스트 줄바꿈 처리
|
||||
$wrappedText = $this->wrapText($caption, 60);
|
||||
$wrappedText = $this->wrapText($caption, 40);
|
||||
$lines = explode("\n", $wrappedText);
|
||||
|
||||
$lineHeight = 30;
|
||||
$startY = $barY + 20 + $lineHeight;
|
||||
$lineHeight = 52;
|
||||
$startY = $barY + 30 + $lineHeight;
|
||||
|
||||
if (count($lines) > 1) {
|
||||
$fontSize = 17;
|
||||
$lineHeight = 26;
|
||||
$startY = $barY + 15 + $lineHeight;
|
||||
$fontSize = 32;
|
||||
$lineHeight = 46;
|
||||
$startY = $barY + 22 + $lineHeight;
|
||||
}
|
||||
|
||||
foreach ($lines as $li => $line) {
|
||||
@@ -194,7 +192,7 @@ private function drawCaptionBar(\GdImage $canvas, string $caption, int $stepNumb
|
||||
imagettftext($canvas, $fontSize, 0, $tx, $startY + ($li * $lineHeight), $white, $this->fontPath, $line);
|
||||
}
|
||||
} else {
|
||||
imagestring($canvas, 5, 40, $textY, $caption, $white);
|
||||
imagestring($canvas, 5, 40, $barY + 80, $caption, $white);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,23 +378,23 @@ public function createIntroSlide(string $title, string $outputPath): ?string
|
||||
|
||||
if (file_exists($this->fontPath)) {
|
||||
// 타이틀
|
||||
$titleSize = 42;
|
||||
$titleSize = 72;
|
||||
$bbox = imagettfbbox($titleSize, 0, $this->fontPath, $title);
|
||||
$tw = $bbox[2] - $bbox[0];
|
||||
$tx = (int) ((self::TARGET_WIDTH - $tw) / 2);
|
||||
imagettftext($canvas, $titleSize, 0, $tx, 460, $white, $this->fontPath, $title);
|
||||
imagettftext($canvas, $titleSize, 0, $tx, 440, $white, $this->fontPath, $title);
|
||||
|
||||
// 서브타이틀
|
||||
$sub = 'SAM 사용법을 안내합니다.';
|
||||
$subSize = 24;
|
||||
$subSize = 40;
|
||||
$bbox2 = imagettfbbox($subSize, 0, $this->fontPath, $sub);
|
||||
$tw2 = $bbox2[2] - $bbox2[0];
|
||||
$tx2 = (int) ((self::TARGET_WIDTH - $tw2) / 2);
|
||||
imagettftext($canvas, $subSize, 0, $tx2, 530, $lightWhite, $this->fontPath, $sub);
|
||||
imagettftext($canvas, $subSize, 0, $tx2, 550, $lightWhite, $this->fontPath, $sub);
|
||||
|
||||
// 구분선
|
||||
$lineColor = imagecolorallocatealpha($canvas, 255, 255, 255, 80);
|
||||
imagefilledrectangle($canvas, (self::TARGET_WIDTH / 2) - 60, 560, (self::TARGET_WIDTH / 2) + 60, 563, $lineColor);
|
||||
imagefilledrectangle($canvas, (self::TARGET_WIDTH / 2) - 80, 590, (self::TARGET_WIDTH / 2) + 80, 594, $lineColor);
|
||||
} else {
|
||||
imagestring($canvas, 5, self::TARGET_WIDTH / 2 - 100, 450, $title, $white);
|
||||
}
|
||||
@@ -441,18 +439,18 @@ public function createOutroSlide(string $title, string $outputPath): ?string
|
||||
|
||||
if (file_exists($this->fontPath)) {
|
||||
$mainText = '이상으로 안내를 마칩니다.';
|
||||
$mainSize = 36;
|
||||
$mainSize = 72;
|
||||
$bbox = imagettfbbox($mainSize, 0, $this->fontPath, $mainText);
|
||||
$tw = $bbox[2] - $bbox[0];
|
||||
$tx = (int) ((self::TARGET_WIDTH - $tw) / 2);
|
||||
imagettftext($canvas, $mainSize, 0, $tx, 470, $white, $this->fontPath, $mainText);
|
||||
imagettftext($canvas, $mainSize, 0, $tx, 440, $white, $this->fontPath, $mainText);
|
||||
|
||||
$subText = '감사합니다.';
|
||||
$subSize = 24;
|
||||
$subSize = 48;
|
||||
$bbox2 = imagettfbbox($subSize, 0, $this->fontPath, $subText);
|
||||
$tw2 = $bbox2[2] - $bbox2[0];
|
||||
$tx2 = (int) ((self::TARGET_WIDTH - $tw2) / 2);
|
||||
imagettftext($canvas, $subSize, 0, $tx2, 530, $lightWhite, $this->fontPath, $subText);
|
||||
imagettftext($canvas, $subSize, 0, $tx2, 560, $lightWhite, $this->fontPath, $subText);
|
||||
} else {
|
||||
imagestring($canvas, 5, self::TARGET_WIDTH / 2 - 100, 470, 'Thank you', $white);
|
||||
}
|
||||
@@ -480,7 +478,7 @@ private function drawNumberMarker(\GdImage $canvas, int $number, int $cx, int $c
|
||||
imageellipse($canvas, $cx, $cy, $r * 2, $r * 2, $white);
|
||||
|
||||
$num = (string) $number;
|
||||
$fontSize = 14;
|
||||
$fontSize = 26;
|
||||
|
||||
if (file_exists($this->fontPath)) {
|
||||
$bbox = imagettfbbox($fontSize, 0, $this->fontPath, $num);
|
||||
@@ -502,21 +500,21 @@ private function drawStepProgressBadge(\GdImage $canvas, int $stepNumber, int $t
|
||||
|
||||
$bx = 30;
|
||||
$by = 20;
|
||||
$bw = 170;
|
||||
$bh = 44;
|
||||
$bw = 300;
|
||||
$bh = 76;
|
||||
|
||||
imagefilledrectangle($canvas, $bx, $by, $bx + $bw, $by + $bh, $badgeBg);
|
||||
|
||||
$text = "STEP {$stepNumber}/{$totalSteps}";
|
||||
|
||||
if (file_exists($this->fontPath)) {
|
||||
$fontSize = 18;
|
||||
$fontSize = 34;
|
||||
$bbox = imagettfbbox($fontSize, 0, $this->fontPath, $text);
|
||||
$tw = $bbox[2] - $bbox[0];
|
||||
$tx = $bx + (int) (($bw - $tw) / 2);
|
||||
imagettftext($canvas, $fontSize, 0, $tx, $by + 32, $white, $this->fontPath, $text);
|
||||
imagettftext($canvas, $fontSize, 0, $tx, $by + 54, $white, $this->fontPath, $text);
|
||||
} else {
|
||||
imagestring($canvas, 5, $bx + 20, $by + 12, $text, $white);
|
||||
imagestring($canvas, 5, $bx + 20, $by + 20, $text, $white);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user