
Card News Generator
- 46 installs
- 902 repo stars
- Updated June 22, 2026
- bear2u/my-skills
Card News Generator is a Claude skill that auto-creates 600x600 Instagram-style card news image series with optional background images.
About
This skill creates 600x600 Instagram-style card news image series for social media. The developer gives a topic and optional colors or background images, and a bundled Python script generates multiple cards with text wrapping, number badges, and an optional dark overlay. It is used to produce social card sets quickly without manual image editing.
- Generates 600x600 Instagram-style card news series with Python
- Supports solid-color or background-image cards with dark overlay for text contrast
- Auto-wraps text and enforces 20-char title / 60-char content limits
Card News Generator by the numbers
- 46 all-time installs (skills.sh)
- Ranked #908 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
card-news-generator capabilities & compatibility
- Capabilities
- image generation · copywriting
- Use cases
- image generation · marketing
- Runs
- Runs locally
- Pricing
- Free
What card-news-generator says it does
Create 600x600 Instagram-style card news series automatically with optional background images.
Size: 600x600 pixels (Instagram-optimized)
npx skills add https://github.com/bear2u/my-skills --skill card-news-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 46 |
|---|---|
| repo stars | ★ 902 |
| Last updated | June 22, 2026 |
| Repository | bear2u/my-skills ↗ |
What it does
Generate a 600x600 Instagram-style card news series from a topic, colors, and optional background images.
Who is it for?
Generating a 5-7 card Instagram-style series on a topic with solid colors or background images.
Skip if: Non-square formats or long-form article layouts.
When should I use this skill?
When the user asks to create card news, an Instagram card series, or social card graphics from a topic.
What you get
A set of numbered 600x600 PNG cards with wrapped text, saved to an output directory.
- 600x600 PNG card images
- numbered card series
By the numbers
- 600x600 pixel canvas
- 5-7 cards per series
- 20-char title / 60-char content limit
Files
Card News Generator - Auto Mode (V2)
Creates beautiful 600x600 card news series for social media with background image support. User can provide topic, colors, and optional background images - Claude handles content generation and multi-card creation automatically.
When to Use
Use this skill when user requests:
- "카드 뉴스 만들어줘"
- "주제로 카드 시리즈 만들어줘"
- "인스타용 카드 생성해줘"
- Any request for visual card content
Core Workflow - AUTO MODE
This is the PRIMARY workflow when users request card news:
Step 1: Get Topic, Colors, and Optional Background Images from User
Ask user for:
- Topic (주제): What the card series is about
- Background RGB (배경색): e.g.,
245,243,238(optional, default: beige) - Background Images (배경 이미지, 선택사항): Path to folder containing images
Example conversation (Solid Color):
Claude: 어떤 주제로 카드 뉴스를 만들까요?
User: Z세대의 특징에 대해서
Claude: 배경색을 선택해주세요 (RGB 형식, 예: 245,243,238)
추천 색상:
• 베이지: 245,243,238
• 핑크: 255,229,229
• 민트: 224,244,241
User: 245,243,238Example conversation (With Background Images):
Claude: 어떤 주제로 카드 뉴스를 만들까요?
User: 여행 팁 5가지
Claude: 배경 이미지를 사용하시겠어요? (사용하려면 이미지 폴더 경로 입력)
User: /path/to/travel-images
Claude: 오버레이 불투명도를 선택하세요 (0.0-1.0, 기본값 0.5)
높을수록 어둡게 처리되어 텍스트가 더 잘 보입니다.
User: 0.6Step 2: Generate Card Content
Create 5-7 cards about the topic. Format output as:
1. [제목]
[설명 2-3줄]
2. [제목]
[설명 2-3줄]
3. [제목]
[설명 2-3줄]CRITICAL Content Guidelines:
- Title: Maximum 20 characters (including spaces)
- Content: Maximum 60 characters (including spaces)
- Keep it concise to fit 600x600 canvas
- Use simple, impactful language
- Each card should convey ONE key point
Step 3: Auto-Generate Cards
Option A: Solid Color Background
Use this command to create all cards with solid color background:
python auto_generator.py \
--topic "Z세대의 특징" \
--bg-color "#f5f3ee" \
--text-color "#1a1a1a" \
--output-dir /mnt/user-data/outputs \
--base-filename "zgen" << 'EOF'
1. 디지털 네이티브
태어날 때부터
디지털 환경에 익숙
2. 개인화 중시
나만의 개성과
취향을 중요시
3. 소통 방식
텍스트보다 영상
이모티콘으로 감정 표현
EOFOption B: Background Images (V2 Feature)
Use this command to create cards with background images:
python auto_generator.py \
--topic "여행 팁" \
--output-dir /mnt/user-data/outputs \
--base-filename "travel" \
--image-folder /path/to/travel-images \
--overlay-opacity 0.6 << 'EOF'
1. 짐 싸기 팁
최소한의 짐으로
가볍게 여행하기
2. 현지 음식
맛집 찾는
나만의 방법
3. 교통 수단
대중교통 활용
팁과 노하우
EOFImportant Notes:
- Images in the folder must be sorted alphabetically/numerically (e.g.,
01.jpg,02.jpg,03.jpg) - Image count should match card count
- If fewer images than cards, remaining cards will use solid color background
- Supported formats:
.jpg,.jpeg,.png,.webp,.bmp - Text automatically changes to white when using background images
The script will automatically:
- Parse the numbered content
- Load background images from the folder (in sorted order)
- Apply dark overlay for better text visibility
- Create individual cards with proper text wrapping
- Save as
travel_01.png,travel_02.png, etc.
Step 4: Provide Download Links
After generation, show user:
✅ 카드 뉴스 5장이 생성되었습니다!
[View card 1](computer:///mnt/user-data/outputs/zgen_01.png)
[View card 2](computer:///mnt/user-data/outputs/zgen_02.png)
...RGB to Hex Conversion
Always convert RGB to hex for scripts:
# RGB 245,243,238 → Hex #f5f3ee
hex_color = '#{:02x}{:02x}{:02x}'.format(245, 243, 238)Recommended Colors (RGB Format)
Show users these options:
- Warm beige:
245,243,238→#f5f3ee - Soft pink:
255,229,229→#ffe5e5 - Mint green:
224,244,241→#e0f4f1 - Lavender:
232,224,245→#e8e0f5 - Peach:
255,232,214→#ffe8d6 - Sky blue:
227,242,253→#e3f2fd
Content Generation Best Practices
Good Card Content Example
1. 디지털 네이티브
태어날 때부터
디지털 환경에 익숙✓ Title: 8 characters ✓ Content: 18 characters ✓ Clear and concise
Bad Card Content Example
1. Z세대는 디지털 네이티브 세대입니다
그들은 태어날 때부터 스마트폰과 인터넷을 사용하며 자랐기 때문에 디지털 기술에 매우 능숙합니다✗ Title too long (21 characters) ✗ Content too long (60+ characters) ✗ Will overflow the 600x600 canvas
Single Card Mode (Manual)
Solid Color Background
For creating just one card with solid color:
python generate_card.py \
--title "제목" \
--content "내용" \
--bg-color "#f5f3ee" \
--text-color "#1a1a1a" \
--number 1 \
--output /mnt/user-data/outputs/single.pngWith Background Image (V2 Feature)
For creating a card with background image:
python generate_card.py \
--title "여행 팁" \
--content "최소한의 짐으로\n가볍게 여행하기" \
--bg-image /path/to/image.jpg \
--overlay-opacity 0.6 \
--number 1 \
--output /mnt/user-data/outputs/travel_01.pngParameters:
--bg-image: Path to background image file--overlay-opacity: Opacity of dark overlay (0.0-1.0, default: 0.5)- 0.0 = No overlay (original image)
- 0.5 = 50% dark overlay (default, good balance)
- 1.0 = Fully black (only for very bright images)
Technical Details
Canvas Specifications
- Size: 600x600 pixels (Instagram-optimized)
- Padding: 40px on all sides
- Max text width: 520px (600 - 80)
- Font sizes:
- Number badge: 60px
- Title: 48px (bold)
- Content: 28px (regular)
Background Image Processing (V2)
- Resize & Crop: Images are automatically resized to 600x600px
- Maintains aspect ratio
- Center crop if aspect ratio differs
- Uses high-quality LANCZOS resampling
- Dark Overlay: Applied to improve text visibility
- Default opacity: 0.5 (50% dark)
- Adjustable via
--overlay-opacity(0.0-1.0) - Higher values = darker overlay = better text contrast
- Text Color: Automatically switches to white (#FFFFFF) when using background images
- Supported Formats: JPG, JPEG, PNG, WebP, BMP
- Image Sorting: Files loaded in alphabetical/numerical order
Text Wrapping
- Automatic word wrapping at max width
- Preserves manual line breaks
- Centers all text horizontally
- Vertical spacing optimized for readability
File Naming Convention
- Auto mode:
{base_filename}_{number:02d}.png - Example:
card_01.png,card_02.png,card_03.png
Error Handling
If text overflows:
- Reduce title length
- Shorten content
- Use line breaks strategically
- Regenerate with revised content
Example Workflows
Example 1: Solid Color Background
User request: "Z세대에 대한 카드 뉴스 5장 만들어줘, 핑크색으로"
Claude response: 1. Confirm: "Z세대 특징에 대한 카드 5장을 핑크 배경(255,229,229)으로 만들겠습니다." 2. Generate 5 cards content (keeping text concise) 3. Run auto_generator.py with heredoc 4. Provide download links to all 5 cards
Total time: ~30 seconds for 5-card series
Example 2: Background Images (V2)
User request: "여행 팁 카드 뉴스 만들어줘, 배경은 /Users/me/travel-photos 폴더에 있는 이미지 사용"
Claude response: 1. Confirm: "여행 팁 카드 뉴스를 만들겠습니다. /Users/me/travel-photos 폴더의 이미지를 배경으로 사용합니다." 2. Ask: "오버레이 불투명도를 선택하세요 (0.0-1.0, 기본값 0.5). 높을수록 텍스트가 더 잘 보입니다." 3. User: "0.6" 4. Generate 5 cards content (keeping text concise) 5. Run auto_generator.py with --image-folder and --overlay-opacity 6. Provide download links showing cards with background images
Preparation tips:
- Rename images in order:
01.jpg,02.jpg,03.jpg,04.jpg,05.jpg - Ensure image count matches card count
- Use high-quality images (at least 600x600px recommended)
- Test with different overlay opacity values for best results
Total time: ~45 seconds for 5-card series with images
#!/usr/bin/env python3
"""
AI-Powered Auto Card News Generator
Creates multiple card news automatically from a topic using Claude API
"""
import argparse
import os
import sys
import json
from pathlib import Path
from generate_card import create_card_news
def get_background_images(image_folder):
"""
Get sorted list of image files from a folder
Args:
image_folder: Path to folder containing background images
Returns:
List of image file paths sorted by filename
"""
if not image_folder or not os.path.exists(image_folder):
return []
# Supported image extensions
extensions = {'.jpg', '.jpeg', '.png', '.webp', '.bmp'}
# Get all image files
image_files = []
for file in sorted(os.listdir(image_folder)):
if Path(file).suffix.lower() in extensions:
image_files.append(os.path.join(image_folder, file))
return image_files
def parse_card_content(content_text):
"""
Parse the AI-generated content into individual cards
Expected format:
1. Title
Description text
2. Title
Description text
"""
cards = []
current_card = None
lines = content_text.strip().split('\n')
for line in lines:
line = line.strip()
if not line:
if current_card and 'content' in current_card:
cards.append(current_card)
current_card = None
continue
# Check if line starts with a number
if line[0].isdigit() and '. ' in line[:5]:
# Save previous card
if current_card and 'content' in current_card:
cards.append(current_card)
# Start new card
parts = line.split('. ', 1)
number = parts[0]
title = parts[1] if len(parts) > 1 else ""
current_card = {
'number': int(number),
'title': title,
'content': ''
}
elif current_card is not None:
# Add to content
if current_card.get('content'):
current_card['content'] += '\n' + line
else:
current_card['content'] = line
# Add last card
if current_card and 'content' in current_card:
cards.append(current_card)
return cards
def generate_cards_from_topic(topic, bg_color, text_color, output_dir, base_filename="card", image_folder=None, overlay_opacity=0.5):
"""
Generate multiple cards from a topic
This function expects Claude (the AI assistant) to have already generated
the card content in the conversation context.
Args:
topic: Main topic for the cards
bg_color: Background color (hex)
text_color: Text color (hex)
output_dir: Directory to save generated cards
base_filename: Base filename for cards
image_folder: Optional folder containing background images
overlay_opacity: Opacity of dark overlay when using background images (0.0-1.0)
"""
print(f"주제: {topic}")
print(f"배경색: {bg_color}")
print(f"텍스트색: {text_color}")
print(f"출력 디렉토리: {output_dir}")
# Load background images if folder is provided
background_images = []
if image_folder:
background_images = get_background_images(image_folder)
if background_images:
print(f"배경 이미지: {len(background_images)}개 발견")
print(f"오버레이 불투명도: {overlay_opacity}")
else:
print(f"⚠️ 배경 이미지 폴더 '{image_folder}'에서 이미지를 찾을 수 없습니다.")
print()
print("=" * 60)
print("Claude가 생성한 카드 내용을 입력하세요.")
print("형식:")
print("1. 제목")
print("설명")
print()
print("2. 제목")
print("설명")
print()
print("입력이 끝나면 Ctrl+D (Linux/Mac) 또는 Ctrl+Z (Windows)를 누르세요.")
print("=" * 60)
print()
# Read all content from stdin
content_text = sys.stdin.read()
# Parse cards
cards = parse_card_content(content_text)
if not cards:
print("❌ 카드 내용을 찾을 수 없습니다.")
return []
print(f"\n✓ {len(cards)}개의 카드를 찾았습니다.\n")
# Warn if not enough background images
if background_images and len(background_images) < len(cards):
print(f"⚠️ 주의: 배경 이미지({len(background_images)}개)가 카드({len(cards)}개)보다 적습니다.")
print(f" 처음 {len(background_images)}개 카드만 배경 이미지를 사용합니다.\n")
# Generate images
generated_files = []
for card in cards:
filename = f"{base_filename}_{card['number']:02d}.png"
output_path = os.path.join(output_dir, filename)
print(f"카드 {card['number']} 생성 중...")
print(f" 제목: {card['title'][:30]}...")
# Get background image for this card (if available)
bg_image = None
if background_images and card['number'] <= len(background_images):
bg_image = background_images[card['number'] - 1]
print(f" 배경: {os.path.basename(bg_image)}")
create_card_news(
title=card['title'],
content=card['content'],
output_path=output_path,
bg_color=bg_color,
text_color=text_color,
number=None, # Number badge removed
bg_image_path=bg_image,
overlay_opacity=overlay_opacity
)
generated_files.append(output_path)
print(f" ✓ 저장: {output_path}\n")
return generated_files
def main():
parser = argparse.ArgumentParser(
description='Generate multiple card news from a topic using AI'
)
parser.add_argument('--topic', required=True, help='Main topic for the card series')
parser.add_argument('--bg-color', default='#F5F3EE', help='Background color (hex)')
parser.add_argument('--text-color', default='#1A1A1A', help='Text color (hex)')
parser.add_argument('--output-dir', default='/mnt/user-data/outputs', help='Output directory')
parser.add_argument('--base-filename', default='card', help='Base filename for cards')
parser.add_argument('--image-folder', help='Folder containing background images (sorted by filename)')
parser.add_argument('--overlay-opacity', type=float, default=0.5, help='Opacity of dark overlay (0.0-1.0, default: 0.5)')
args = parser.parse_args()
# Ensure output directory exists
os.makedirs(args.output_dir, exist_ok=True)
# Generate cards
files = generate_cards_from_topic(
topic=args.topic,
bg_color=args.bg_color,
text_color=args.text_color,
output_dir=args.output_dir,
base_filename=args.base_filename,
image_folder=args.image_folder,
overlay_opacity=args.overlay_opacity
)
if files:
print("=" * 60)
print(f"✅ 완료! {len(files)}개의 카드가 생성되었습니다.")
print("=" * 60)
for f in files:
print(f" 📁 {f}")
else:
print("❌ 카드 생성 실패")
sys.exit(1)
if __name__ == '__main__':
main()
카드 뉴스 자동 생성기 - 완벽 가이드
🎯 핵심 변경사항
✨ 새로운 기능
- 600x600 사이즈: 인스타그램 최적화
- 자동 텍스트 래핑: 텍스트가 절대 잘리지 않음
- AI 자동 생성: 주제만 입력하면 여러 장 자동 생성
- 간편한 워크플로우: 유저는 주제 + 배경색만 제공
🚀 사용 방법
기본 사용법 (추천)
유저가 제공하는 것: 1. 주제 (예: "Z세대의 특징") 2. 배경색 RGB (예: 245,243,238)
Claude가 하는 것: 1. 주제에 맞는 5-7개 카드 내용 생성 2. 자동으로 모든 카드 이미지 생성 3. 다운로드 링크 제공
예시 대화
유저: Z세대에 대한 카드 뉴스 만들어줘
Claude: Z세대 특징에 대한 카드 뉴스를 만들겠습니다!
배경색을 선택해주세요 (RGB 형식):
추천 색상:
• 베이지: 245,243,238
• 핑크: 255,229,229
• 민트: 224,244,241
유저: 핑크로 해줘
Claude: 알겠습니다! Z세대 특징 카드 5장을 핑크 배경으로 생성하겠습니다.
[카드 내용 생성 및 이미지 생성]
✅ 카드 뉴스 5장이 완성되었습니다!
[카드 1 다운로드]
[카드 2 다운로드]
...📝 콘텐츠 생성 가이드라인
제목 작성
- 최대 20자 (공백 포함)
- 간결하고 임팩트 있게
- 핵심 키워드 중심
✅ 좋은 예:
- "디지털 네이티브"
- "개인화 중시"
- "소통 방식 변화"
❌ 나쁜 예:
- "Z세대는 디지털 네이티브 세대입니다" (너무 길다)
- "특징" (너무 짧고 모호)
설명 작성
- 최대 60자 (공백 포함)
- 2-3줄로 나누기
- 각 줄은 15-20자 정도
✅ 좋은 예:
태어날 때부터
디지털 환경에 익숙❌ 나쁜 예:
그들은 태어날 때부터 스마트폰과 인터넷을 사용하며 자랐기 때문에 디지털 기술에 매우 능숙합니다🎨 색상 가이드
RGB 형식으로 입력
베이지: 245,243,238
핑크: 255,229,229
민트: 224,244,241
라벤더: 232,224,245
피치: 255,232,214
블루: 227,242,253색상별 추천 용도
| 색상 | RGB | 용도 |
|---|---|---|
| 🏜️ 베이지 | 245,243,238 | 전문적, 중립적 주제 |
| 🌸 핑크 | 255,229,229 | 부드럽고 감성적인 주제 |
| 🌿 민트 | 224,244,241 | 자연, 건강, 웰빙 |
| 💜 라벤더 | 232,224,245 | 힐링, 마인드풀니스 |
| 🍑 피치 | 255,232,214 | 따뜻하고 친근한 주제 |
| 🌤️ 블루 | 227,242,253 | 비즈니스, 신뢰성 |
🛠️ 기술 사양
캔버스 크기
- 크기: 600x600 픽셀
- 패딩: 40px (상하좌우)
- 텍스트 영역: 520px 최대 폭
폰트 크기
- 번호 배지: 60px (볼드)
- 제목: 48px (볼드)
- 설명: 28px (레귤러)
레이아웃
┌─────────────────────────┐
│ [번호] │ ← 60px, 상단에서 60px
│ │
│ [제목] │ ← 48px, 볼드, 중앙정렬
│ │
│ [설명] │ ← 28px, 중앙정렬
│ │
│ │
└─────────────────────────┘
600x600px📋 Claude 사용 시나리오
시나리오 1: 기본 카드 뉴스 생성
유저 입력:
"밀레니얼 세대 특징으로 카드 뉴스 5장 만들어줘. 민트색으로."Claude 워크플로우: 1. 주제 확인: "밀레니얼 세대 특징" 2. 색상 확인: 민트 (224,244,241) 3. 5개 카드 내용 생성 (각 20자 이하 제목 + 60자 이하 설명) 4. auto_generator.py 실행 5. 다운로드 링크 제공
시나리오 2: 커스텀 색상
유저 입력:
"건강한 아침 습관에 대한 카드를 만들어줘.
배경은 RGB 200,230,201로 해줘."Claude 워크플로우: 1. RGB를 Hex로 변환: #c8e6c9 2. 건강 관련 내용 5-7개 생성 3. auto_generator.py로 카드 생성 4. 결과 제공
시나리오 3: 시리즈물
유저 입력:
"Python 기초 강좌를 카드 뉴스로 만들어줘.
10장 정도로, 파란색 배경으로."Claude 워크플로우: 1. Python 기초 10개 주제 선정 2. 각 주제별 간결한 설명 작성 3. 블루 배경 (227,242,253)으로 10장 생성 4. 순차적 번호와 함께 제공
💡 팁 & 트릭
1. 텍스트 길이 최적화
# 제목 길이 체크
title = "디지털 네이티브"
if len(title) <= 20: # ✓ Good
# 설명 길이 체크
content = "태어날 때부터\n디지털 환경에 익숙"
if len(content.replace('\n', '')) <= 60: # ✓ Good2. 줄바꿈 전략
# 자연스러운 줄바꿈
태어날 때부터
디지털 환경에 익숙
# 읽기 편한 리듬
나만의 개성과
취향을 중요시3. 시리즈 일관성
- 모든 카드에 같은 배경색 사용
- 제목 길이 비슷하게 유지
- 설명 스타일 통일
4. 숫자 효과적 사용
1. [소개/정의]
2. [핵심 특징 1]
3. [핵심 특징 2]
4. [핵심 특징 3]
5. [결론/행동 촉구]🔧 문제 해결
Q: 텍스트가 여전히 잘려요
A: 내용이 너무 깁니다. 제목 20자, 설명 60자 이하로 줄이세요.
Q: 폰트가 안 나와요
A: 한글 폰트 설치 확인:
sudo apt-get install fonts-noto-cjk
fc-cache -fvQ: 자동 생성이 안 돼요
A: 콘텐츠 형식 확인:
1. 제목
설명
2. 제목
설명번호와 제목 사이에 . (마침표 + 공백) 필요
Q: 이미지 품질이 떨어져요
A: PNG 품질은 95%로 설정되어 있습니다. 충분히 고품질입니다.
📱 플랫폼별 최적화
인스타그램
- 크기: 600x600 (기본값) ✓
- 형식: PNG
- 업로드: 그대로 사용
페이스북
- 크기: 600x600 ✓
- 권장: 밝은 배경색 사용
카카오톡
- 크기: 600x600 ✓
- 팁: 텍스트 크기 충분히 확보
블로그 썸네일
- 600x600 정사각형 그대로 사용 가능
- 또는 --width --height로 커스텀
🎓 고급 활용
커스텀 크기 생성
python generate_card.py \
--title "제목" \
--content "내용" \
--width 800 \
--height 800 \
--output custom.png폰트 크기 조정
python generate_card.py \
--title "제목" \
--content "내용" \
--title-size 60 \
--content-size 35 \
--output larger_text.png번호 없이 생성
python generate_card.py \
--title "제목" \
--content "내용" \
--output no_number.png
# --number 옵션 생략📊 성능
- 생성 속도: 카드 1장당 ~0.5초
- 시리즈 생성: 5장 기준 ~3초
- 메모리: ~50MB per card
- 파일 크기: 평균 30-50KB per PNG
📄 라이선스
MIT License - 자유롭게 사용, 수정, 배포 가능
---
즐거운 카드 뉴스 제작 되세요! 🎉
#!/usr/bin/env python3
"""
Card News Generator
Creates beautiful social media card images with Korean text support
"""
import argparse
import os
from PIL import Image, ImageDraw, ImageFont
import textwrap
import sys
def resize_and_crop(img, target_width, target_height):
"""
Resize and crop image to fit target dimensions while maintaining aspect ratio
Centers the crop
"""
# Get current dimensions
width, height = img.size
# Calculate aspect ratios
target_ratio = target_width / target_height
current_ratio = width / height
if current_ratio > target_ratio:
# Image is wider than target - crop width
new_height = target_height
new_width = int(new_height * current_ratio)
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Crop center
left = (new_width - target_width) // 2
img = img.crop((left, 0, left + target_width, target_height))
else:
# Image is taller than target - crop height
new_width = target_width
new_height = int(new_width / current_ratio)
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Crop center
top = (new_height - target_height) // 2
img = img.crop((0, top, target_width, top + target_height))
return img
def wrap_text(text, font, max_width, draw):
"""Wrap text to fit within max_width"""
words = text.split()
lines = []
current_line = []
for word in words:
test_line = ' '.join(current_line + [word])
bbox = draw.textbbox((0, 0), test_line, font=font)
width = bbox[2] - bbox[0]
if width <= max_width:
current_line.append(word)
else:
if current_line:
lines.append(' '.join(current_line))
current_line = [word]
else:
# Word is too long, force it
lines.append(word)
if current_line:
lines.append(' '.join(current_line))
return lines
def create_card_news(
title,
content,
output_path,
bg_color="#F5F3EE",
text_color="#1A1A1A",
width=600,
height=600,
title_size=48,
content_size=28,
number=None,
bg_image_path=None,
overlay_opacity=0.5
):
"""
Generate a card news image with vertically centered content
Args:
title: Main title text
content: Body content text
output_path: Path to save the image
bg_color: Background color (hex)
text_color: Text color (hex)
width: Image width in pixels (default 600)
height: Image height in pixels (default 600)
title_size: Title font size (default 48)
content_size: Content font size (default 28)
number: Optional number badge (e.g., 1, 2, 3)
bg_image_path: Optional path to background image
overlay_opacity: Opacity of dark overlay when using background image (0.0-1.0, default 0.5)
"""
# Create image with background
if bg_image_path and os.path.exists(bg_image_path):
# Load and resize background image
try:
bg_img = Image.open(bg_image_path)
# Convert to RGB if necessary
if bg_img.mode != 'RGB':
bg_img = bg_img.convert('RGB')
# Resize to fit canvas (crop center if aspect ratio differs)
bg_img = resize_and_crop(bg_img, width, height)
img = bg_img
# Add dark overlay for better text visibility
overlay = Image.new('RGB', (width, height), (0, 0, 0))
img = Image.blend(img, overlay, overlay_opacity)
# Use white text on background images
if text_color == "#1A1A1A": # Default dark color
text_color = "#FFFFFF"
except Exception as e:
print(f"Warning: Could not load background image {bg_image_path}: {e}", file=sys.stderr)
print("Falling back to solid color background", file=sys.stderr)
img = Image.new('RGB', (width, height), bg_color)
else:
# Create image with background color
img = Image.new('RGB', (width, height), bg_color)
draw = ImageDraw.Draw(img)
# Padding
padding = 40
# Reduce max text width for more compact, square-like box
max_text_width = int(width * 0.65) # Use 65% of canvas width instead of full width
# Try to load fonts (fallback to default if not available)
# Get script directory for relative font path
script_dir = os.path.dirname(os.path.abspath(__file__))
# Cafe24Ssurround font (bundled with skill)
cafe24_font = os.path.join(script_dir, "fonts", "Cafe24Ssurround-v2.0.ttf")
# macOS font paths
macos_fonts = [
"/System/Library/Fonts/AppleSDGothicNeo.ttc",
"/System/Library/Fonts/Supplemental/AppleGothic.ttf",
"/System/Library/Fonts/Supplemental/NotoSansGothic-Regular.ttf",
"/Library/Fonts/Arial Unicode.ttf"
]
# Linux font paths
linux_fonts = [
"/usr/share/fonts/truetype/noto/NotoSansCJK-Bold.ttc",
"/usr/share/fonts/truetype/noto/NotoSansKR-Bold.ttf",
"/usr/share/fonts/noto-cjk/NotoSansCJK-Bold.ttc"
]
# Combine all font paths (Cafe24 first, then system fonts)
all_fonts = [cafe24_font] + macos_fonts + linux_fonts
# Load title font (bold)
title_font = None
for font_path in all_fonts:
try:
title_font = ImageFont.truetype(font_path, title_size)
print(f"Using font: {os.path.basename(font_path)} for title", file=sys.stderr)
break
except:
continue
if title_font is None:
print("Warning: Korean font not found, using default font", file=sys.stderr)
title_font = ImageFont.load_default()
# Load content font (regular)
content_font = None
for font_path in all_fonts:
try:
content_font = ImageFont.truetype(font_path, content_size)
break
except:
continue
if content_font is None:
content_font = ImageFont.load_default()
# Load number font (bold)
number_font = None
for font_path in all_fonts:
try:
number_font = ImageFont.truetype(font_path, 60)
break
except:
continue
if number_font is None:
number_font = ImageFont.load_default()
# Calculate total content height first
number_height = 0
if number is not None:
number_text = str(number)
bbox = draw.textbbox((0, 0), number_text, font=number_font)
number_height = bbox[3] - bbox[1] + 40 # height + spacing
# Wrap and measure title
title_lines = []
for line in title.split('\n'):
wrapped = wrap_text(line, title_font, max_text_width, draw)
title_lines.extend(wrapped)
title_height = 0
for line in title_lines:
bbox = draw.textbbox((0, 0), line, font=title_font)
title_height += bbox[3] - bbox[1] + 10
# Wrap and measure content
content_lines = []
for line in content.split('\n'):
wrapped = wrap_text(line, content_font, max_text_width, draw)
content_lines.extend(wrapped)
content_height = 0
for line in content_lines:
bbox = draw.textbbox((0, 0), line, font=content_font)
content_height += bbox[3] - bbox[1] + 8
# Calculate total height and starting Y position for vertical centering
spacing_between = 30
total_content_height = number_height + title_height + spacing_between + content_height
start_y = (height - total_content_height) // 2
# Draw semi-transparent box around text area (more compact, square-like)
box_padding = 40
# Calculate box width based on text width
box_width = max_text_width + (box_padding * 2)
box_height = total_content_height + (box_padding * 2)
# Center the box horizontally
box_left = (width - box_width) // 2
box_top = start_y - box_padding
box_right = box_left + box_width
box_bottom = start_y + total_content_height + box_padding
# Create semi-transparent black box
overlay_box = Image.new('RGBA', (width, height), (0, 0, 0, 0))
box_draw = ImageDraw.Draw(overlay_box)
# Draw filled box with transparency
box_draw.rounded_rectangle(
[(box_left, box_top), (box_right, box_bottom)],
radius=20,
fill=(0, 0, 0, 100) # Semi-transparent black
)
# Draw border
box_draw.rounded_rectangle(
[(box_left, box_top), (box_right, box_bottom)],
radius=20,
outline=(255, 255, 255, 180), # White border
width=3
)
# Composite the box onto the main image
img = Image.alpha_composite(img.convert('RGBA'), overlay_box).convert('RGB')
draw = ImageDraw.Draw(img)
current_y = start_y
# Draw number badge if provided
if number is not None:
number_text = str(number)
bbox = draw.textbbox((0, 0), number_text, font=number_font)
number_width = bbox[2] - bbox[0]
number_x = (width - number_width) // 2
draw.text((number_x, current_y), number_text, fill=text_color, font=number_font)
current_y += bbox[3] - bbox[1] + 40
# Draw title
for line in title_lines:
bbox = draw.textbbox((0, 0), line, font=title_font)
line_width = bbox[2] - bbox[0]
line_height = bbox[3] - bbox[1]
x = (width - line_width) // 2
draw.text((x, current_y), line, fill=text_color, font=title_font)
current_y += line_height + 10
current_y += spacing_between # Space between title and content
# Draw content
for line in content_lines:
bbox = draw.textbbox((0, 0), line, font=content_font)
line_width = bbox[2] - bbox[0]
line_height = bbox[3] - bbox[1]
x = (width - line_width) // 2
draw.text((x, current_y), line, fill=text_color, font=content_font)
current_y += line_height + 8
# Save image
img.save(output_path, 'PNG', quality=95)
print(f"Card news generated successfully: {output_path}")
def main():
parser = argparse.ArgumentParser(
description='Generate card news images with Korean text support'
)
# Required arguments
parser.add_argument('--title', required=True, help='Main title text')
parser.add_argument('--content', required=True, help='Body content text')
parser.add_argument('--output', required=True, help='Output file path')
# Optional arguments
parser.add_argument('--bg-color', default='#F5F3EE', help='Background color (hex)')
parser.add_argument('--text-color', default='#1A1A1A', help='Text color (hex)')
parser.add_argument('--width', type=int, default=600, help='Image width (default: 600)')
parser.add_argument('--height', type=int, default=600, help='Image height (default: 600)')
parser.add_argument('--title-size', type=int, default=48, help='Title font size (default: 48)')
parser.add_argument('--content-size', type=int, default=28, help='Content font size (default: 28)')
parser.add_argument('--number', type=int, help='Optional number badge')
parser.add_argument('--bg-image', help='Path to background image')
parser.add_argument('--overlay-opacity', type=float, default=0.5, help='Opacity of dark overlay (0.0-1.0, default: 0.5)')
args = parser.parse_args()
create_card_news(
title=args.title,
content=args.content,
output_path=args.output,
bg_color=args.bg_color,
text_color=args.text_color,
width=args.width,
height=args.height,
title_size=args.title_size,
content_size=args.content_size,
number=args.number,
bg_image_path=args.bg_image,
overlay_opacity=args.overlay_opacity
)
if __name__ == '__main__':
main()
인터랙티브 모드 사용 데모
실행 방법
cd /mnt/user-data/outputs/card-news-generator
python interactive_generator.py실행 화면 예시
==================================================
📱 카드 뉴스 생성기
==================================================
1️⃣ 제목을 입력하세요
(줄바꿈하려면 Enter를 누르고 계속 입력)
(여러 줄 입력 가능. 빈 줄을 입력하면 종료)
>>> 선생님·부모보다
>>> 유튜브 등을 더 신뢰함
>>>
2️⃣ 본문 내용을 입력하세요
(여러 줄 입력 가능. 빈 줄을 입력하면 종료)
>>> 정보 접근이 빠르고,
>>> 권위보다 '속도'를 더 신뢰함.
>>>
3️⃣ 배경색을 선택하세요
추천 색상:
• 따뜻한 베이지: 245,243,238
• 소프트 핑크: 255,229,229
• 민트 그린: 224,244,241
• 라벤더: 232,224,245
• 피치: 255,232,214
• 스카이 블루: 227,242,253
배경색 RGB
형식: R,G,B (예: 245,243,238 또는 빈 값 입력시 기본값: #F5F3EE)
>>> 245,243,238
✓ 선택된 색상: #f5f3ee
4️⃣ 텍스트 색상을 선택하세요
텍스트 RGB
형식: R,G,B (예: 245,243,238 또는 빈 값 입력시 기본값: #1A1A1A)
>>>
⚠️ RGB 값은 3개여야 합니다. 기본값을 사용합니다.
5️⃣ 카드 번호를 입력하세요 (선택사항)
(빈 값 입력시 번호 없음)
>>> 1
✓ 번호: 1
6️⃣ 저장할 파일명을 입력하세요
(예: card_01.png)
>>> my_first_card.png
==================================================
🎨 카드 생성 중...
==================================================
Card news generated successfully: /mnt/user-data/outputs/my_first_card.png
✅ 완료!
📁 저장 위치: /mnt/user-data/outputs/my_first_card.pngRGB 색상 입력 가이드
올바른 입력 예시
245,243,238 ✓ 정상
255,229,229 ✓ 정상
0,0,0 ✓ 정상 (검정)
255,255,255 ✓ 정상 (흰색)잘못된 입력 예시
#f5f3ee ✗ Hex 코드 불가 (RGB만 가능)
245 243 238 ✗ 쉼표 없음
245,243 ✗ 값이 2개만 있음
300,243,238 ✗ 값이 255 초과빈 값 입력
(Enter만 누르기) → 기본값 사용Claude에게 요청하는 방법
방법 1: 인터랙티브 모드 실행 요청
카드 뉴스를 만들고 싶어.
인터랙티브 모드로 실행해서 내가 직접 입력할게.방법 2: 정보를 모두 제공
다음 내용으로 카드 뉴스를 만들어줘:
제목: 선생님·부모보다
유튜브 등을 더 신뢰함
내용: 정보 접근이 빠르고,
권위보다 '속도'를 더 신뢰함.
배경색: 245,243,238 (베이지)
텍스트: 26,26,26 (검정)
번호: 1
파일명: card_01.pngClaude가 자동으로 RGB를 Hex로 변환하고 카드를 생성합니다.
색상 조합 치트시트
복사해서 바로 사용할 수 있는 RGB 값:
| 스타일 | 배경 RGB | 텍스트 RGB |
|---|---|---|
| 🏜️ 베이지 | 245,243,238 | 26,26,26 |
| 🌸 핑크 | 255,229,229 | 44,24,16 |
| 🌿 민트 | 224,244,241 | 26,26,26 |
| 💜 라벤더 | 232,224,245 | 44,24,16 |
| 🍑 피치 | 255,232,214 | 44,24,16 |
| 🌤️ 블루 | 227,242,253 | 26,26,26 |
팁
1. 줄바꿈: 제목이나 내용에서 Enter를 누르면 자동으로 줄바꿈됩니다 2. 기본값 사용: 색상 입력에서 Enter만 누르면 기본 베이지색 사용 3. 번호 생략: 시리즈가 아니면 번호 입력에서 Enter만 누르세요 4. 파일명 자동 확장: .png를 안 붙여도 자동으로 추가됩니다
문제 해결
Q: RGB 값을 잘못 입력했어요
- 기본값이 자동으로 적용됩니다. 다시 실행하세요.
Q: 한글이 깨져서 나와요
sudo apt-get install fonts-noto-cjkQ: 스크립트가 실행이 안 돼요
chmod +x interactive_generator.py
pip install Pillow --break-system-packages#!/usr/bin/env python3
"""
Interactive Card News Generator
Prompts user for title, content, and background color
"""
import sys
from generate_card import create_card_news
def get_multiline_input(prompt):
"""Get multiline input from user"""
print(prompt)
print("(여러 줄 입력 가능. 빈 줄을 입력하면 종료)")
lines = []
while True:
line = input()
if line == "":
break
lines.append(line)
return "\n".join(lines)
def get_color_input(prompt, default):
"""Get color input in RGB format"""
print(prompt)
print(f"형식: R,G,B (예: 245,243,238 또는 빈 값 입력시 기본값: {default})")
color_input = input(">>> ").strip()
if not color_input:
return default
try:
# Parse RGB values
rgb = [int(x.strip()) for x in color_input.split(',')]
if len(rgb) != 3:
print("⚠️ RGB 값은 3개여야 합니다. 기본값을 사용합니다.")
return default
# Validate range
for val in rgb:
if not (0 <= val <= 255):
print("⚠️ RGB 값은 0-255 범위여야 합니다. 기본값을 사용합니다.")
return default
# Convert to hex
hex_color = '#{:02x}{:02x}{:02x}'.format(rgb[0], rgb[1], rgb[2])
print(f"✓ 선택된 색상: {hex_color}")
return hex_color
except ValueError:
print("⚠️ 올바른 형식이 아닙니다. 기본값을 사용합니다.")
return default
def main():
print("=" * 50)
print(" 📱 카드 뉴스 생성기")
print("=" * 50)
print()
# Get title
print("1️⃣ 제목을 입력하세요")
print(" (줄바꿈하려면 Enter를 누르고 계속 입력)")
title = get_multiline_input("")
if not title:
print("❌ 제목은 필수입니다.")
sys.exit(1)
print()
# Get content
print("2️⃣ 본문 내용을 입력하세요")
content = get_multiline_input("")
if not content:
print("❌ 내용은 필수입니다.")
sys.exit(1)
print()
# Get background color
print("3️⃣ 배경색을 선택하세요")
print("\n추천 색상:")
print(" • 따뜻한 베이지: 245,243,238")
print(" • 소프트 핑크: 255,229,229")
print(" • 민트 그린: 224,244,241")
print(" • 라벤더: 232,224,245")
print(" • 피치: 255,232,214")
print(" • 스카이 블루: 227,242,253")
print()
bg_color = get_color_input("배경색 RGB", "#F5F3EE")
print()
# Get text color
print("4️⃣ 텍스트 색상을 선택하세요")
text_color = get_color_input("텍스트 RGB", "#1A1A1A")
print()
# Get number badge (optional)
print("5️⃣ 카드 번호를 입력하세요 (선택사항)")
print(" (빈 값 입력시 번호 없음)")
number_input = input(">>> ").strip()
number = None
if number_input:
try:
number = int(number_input)
print(f"✓ 번호: {number}")
except ValueError:
print("⚠️ 올바른 숫자가 아닙니다. 번호 없이 생성합니다.")
print()
# Get output filename
print("6️⃣ 저장할 파일명을 입력하세요")
print(" (예: card_01.png)")
filename = input(">>> ").strip()
if not filename:
filename = "card.png"
if not filename.endswith('.png'):
filename += '.png'
output_path = f"/mnt/user-data/outputs/{filename}"
print()
print("=" * 50)
print("🎨 카드 생성 중...")
print("=" * 50)
# Generate card
try:
create_card_news(
title=title,
content=content,
output_path=output_path,
bg_color=bg_color,
text_color=text_color,
number=number
)
print()
print("✅ 완료!")
print(f"📁 저장 위치: {output_path}")
except Exception as e:
print(f"❌ 오류 발생: {e}")
sys.exit(1)
if __name__ == '__main__':
main()
카드 뉴스 생성기 스킬 - 빠른 시작 가이드
🎯 이 스킬은 무엇인가요?
소셜 미디어(인스타그램, 페이스북, 카카오톡 등)에 올릴 수 있는 텍스트 기반 카드 뉴스 이미지를 자동으로 생성하는 Claude 스킬입니다.
✨ 주요 기능
- ✅ 한글 텍스트 완벽 지원
- ✅ 커스텀 배경색 및 텍스트 색상
- ✅ 자동 중앙 정렬 및 레이아웃
- ✅ 숫자 배지 지원 (시리즈물)
- ✅ 다양한 이미지 크기 지원
📦 설치 방법
1단계: 스킬 폴더 설정
# Claude Code의 skills 디렉토리에 압축 해제
cd ~/.claude/skills/user
tar -xzf card-news-generator.tar.gz2단계: 필요한 패키지 설치
pip install Pillow --break-system-packages3단계: 한글 폰트 설치 (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y fonts-noto-cjk🚀 사용 방법
방법 1: 인터랙티브 모드 (초보자 추천)
가장 쉬운 방법입니다. Claude에게 이렇게 요청하세요:
카드 뉴스를 만들고 싶어. 인터랙티브 모드로 실행해줘.그러면 Claude가 interactive_generator.py를 실행하고, 다음을 차례로 물어봅니다:
1. 제목 입력 (여러 줄 가능)
선생님·부모보다
유튜브 등을 더 신뢰함
(빈 줄 입력으로 완료)2. 내용 입력 (여러 줄 가능)
정보 접근이 빠르고,
권위보다 '속도'를 더 신뢰함.
(빈 줄 입력으로 완료)3. 배경색 선택 (RGB 형식)
추천 색상이 표시됩니다:
• 따뜻한 베이지: 245,243,238
• 소프트 핑크: 255,229,229
• 민트 그린: 224,244,241
등등...
원하는 색상 입력: 245,243,2384. 텍스트 색상 (RGB 형식)
기본값 사용하려면 빈 값 입력
또는 RGB 값 입력: 26,26,265. 카드 번호 (선택사항)
16. 파일명
card_01.png완료! 카드가 자동으로 생성됩니다.
방법 2: Claude에게 직접 요청 (빠른 방법)
모든 정보를 한 번에 제공:
제목: "선생님·부모보다 유튜브 등을 더 신뢰함"
내용: "정보 접근이 빠르고, 권위보다 '속도'를 더 신뢰함."
배경색: RGB 245,243,238 (따뜻한 베이지)
텍스트: RGB 26,26,26 (검정)
번호: 1
이 내용으로 카드 뉴스를 만들어줘.Claude가 자동으로 RGB 값을 Hex로 변환하고 카드를 생성합니다.
고급 사용법
커스텀 색상 지정
핑크색 배경으로 카드를 만들어줘.
제목: "나만의 제목"
내용: "나만의 내용"
배경 RGB: 255,229,229
텍스트 RGB: 44,24,16정사각형 포맷 (인스타그램)
1080x1080 정사각형으로 카드를 만들어줘.
제목과 내용은 인터랙티브로 입력할게.시리즈 카드 생성
다음 내용으로 3개의 카드 뉴스 시리즈를 만들어줘.
모두 베이지 배경(245,243,238)으로 통일:
1. 제목: "첫 번째", 내용: "첫 번째 설명"
2. 제목: "두 번째", 내용: "두 번째 설명"
3. 제목: "세 번째", 내용: "세 번째 설명"🎨 추천 색상 조합
| 스타일 | 배경 RGB | 텍스트 RGB | Hex (참고) | 용도 |
|---|---|---|---|---|
| 클래식 베이지 | 245,243,238 | 26,26,26 | #f5f3ee / #1a1a1a | 기본, 모든 주제 |
| 소프트 핑크 | 255,229,229 | 44,24,16 | #ffe5e5 / #2c1810 | 부드러운 주제 |
| 민트 프레시 | 224,244,241 | 26,26,26 | #e0f4f1 / #1a1a1a | 자연, 건강 |
| 감성 라벤더 | 232,224,245 | 44,24,16 | #e8e0f5 / #2c1810 | 힐링, 감성 |
| 따뜻한 피치 | 255,232,214 | 44,24,16 | #ffe8d6 / #2c1810 | 활력, 따뜻함 |
| 프로페셔널 블루 | 227,242,253 | 26,26,26 | #e3f2fd / #1a1a1a | 비즈니스, 전문성 |
색상 선택 팁:
- 인터랙티브 모드: RGB 값 그대로 입력 (예:
245,243,238) - Claude에게 요청: "베이지 배경", "핑크 배경" 등으로 말해도 됩니다
📐 이미지 크기 가이드
| 플랫폼 | 권장 크기 | 용도 |
|---|---|---|
| 인스타그램 스토리 | 1080 x 1920 | 세로형 풀스크린 |
| 인스타그램 피드 | 1080 x 1080 | 정사각형 |
| 페이스북 포스트 | 1200 x 630 | 가로형 |
| 카카오톡 | 1080 x 1920 | 세로형 |
| 블로그 썸네일 | 1200 x 630 | 가로형 |
💡 팁 & 트릭
1. 텍스트 줄바꿈
긴 제목이나 내용은 자연스러운 위치에서 줄바꿈하세요:
제목: "선생님·부모보다\n유튜브 등을 더 신뢰함"2. 시리즈물 일관성
시리즈로 여러 장을 만들 때는 같은 배경색을 사용하세요:
모든 카드를 베이지색(#F5F3EE) 배경으로 통일해줘.3. 가독성 최적화
- 제목은 15자 내외로 간결하게
- 본문은 30자 내외로 핵심만
- 밝은 배경에는 어두운 텍스트
- 어두운 배경에는 밝은 텍스트
4. 브랜딩
고유한 색상 조합을 정해서 일관되게 사용하면 브랜드 인지도가 높아집니다.
🔧 문제 해결
Q: 한글이 깨져서 나와요
# 폰트 재설치
sudo apt-get install --reinstall fonts-noto-cjk
fc-cache -fvQ: "PIL" 모듈을 찾을 수 없다고 나와요
pip install --upgrade Pillow --break-system-packagesQ: 이미지가 생성은 되는데 다운로드 링크가 안 보여요
Claude가 /mnt/user-data/outputs/ 폴더에 저장했는지 확인하고, computer:// 링크를 제공하도록 요청하세요.
Q: 텍스트가 너무 작거나 커요
폰트 크기를 조정해 달라고 요청하세요:
제목 폰트 크기를 150으로, 본문은 70으로 조정해줘.📝 예제 모음
예제 1: 인터랙티브 모드로 기본 카드
카드 뉴스를 인터랙티브 모드로 만들어줘.
→ 제목: 오늘의 명언
→ 내용: 작은 실천이\n큰 변화를 만든다
→ 배경 RGB: 245,243,238 (또는 Enter로 기본값)
→ 텍스트 RGB: (Enter로 기본값)
→ 번호: (Enter로 생략)
→ 파일명: quote_card.png예제 2: 직접 명령으로 정보 전달
제목: "앱 업데이트 안내"
내용: "v2.0 버전이 출시되었습니다.\n새로운 기능을 확인하세요!"
배경: 베이지 (245,243,238)
번호: 1
파일명: update_card.png
이 내용으로 카드를 만들어줘.예제 3: 이벤트 공지 (커스텀 색상)
제목: "특별 할인 이벤트"
내용: "지금 가입하면\n첫 달 50% 할인"
배경: 피치색 (255,232,214)
텍스트: 갈색 (44,24,16)
이렇게 카드 만들어줘.예제 4: 교육 콘텐츠 시리즈
Python 기초 시리즈를 3장 만들어줘.
모두 스카이블루 배경 (227,242,253)으로:
1. 제목: "Python 기초", 내용: "변수란 데이터를\n저장하는 공간입니다"
2. 제목: "Python 기초", 내용: "함수는 코드를\n재사용 가능하게 합니다"
3. 제목: "Python 기초", 내용: "리스트는 여러 값을\n순서대로 저장합니다"🎓 고급 활용
자동화된 시리즈 생성
JSON 형식으로 여러 카드 내용을 제공하면 Claude가 자동으로 시리즈를 생성합니다:
[
{"title": "첫 번째 주제", "content": "첫 번째 설명"},
{"title": "두 번째 주제", "content": "두 번째 설명"},
{"title": "세 번째 주제", "content": "세 번째 설명"}
]브랜드 색상 세트 저장
자주 사용하는 색상 조합을 Claude에게 기억하도록 요청:
우리 브랜드 색상은 배경 RGB 245,243,238, 텍스트 RGB 44,24,16이야.
앞으로 카드 만들 때 이 색상을 기본으로 써줘.참고: Claude는 RGB 값을 자동으로 Hex 코드로 변환해서 명령어를 실행합니다. 예: RGB 245,243,238 → Hex #f5f3ee
📄 라이선스
MIT License - 자유롭게 사용, 수정, 배포 가능합니다.
🙋♂️ 도움이 필요하신가요?
Claude에게 다음과 같이 물어보세요:
- "카드 뉴스 스킬 사용법 알려줘"
- "다른 배경색 추천해줘"
- "이 카드를 정사각형으로 다시 만들어줘"
- "텍스트 크기를 조정해줘"
즐거운 카드 뉴스 제작 되세요! 🎉
Card News Generator Skill V2
한국어 텍스트를 지원하는 소셜 미디어용 카드 뉴스 이미지 생성 스킬입니다.
특징
V2 새로운 기능 🆕
- ✨ 배경 이미지 지원: 폴더의 이미지를 배경으로 자동 적용
- ✨ Cafe24Ssurround 폰트: 번들 폰트 포함, 별도 설치 불필요
- ✨ 자동 텍스트 색상: 배경 이미지 사용 시 흰색으로 자동 전환
- ✨ 오버레이 조절: 텍스트 가독성을 위한 어두운 오버레이 (조절 가능)
- ✨ 반투명 박스 + 테두리: 텍스트 영역에 둥근 박스와 흰색 테두리
- ✨ 컴팩트 디자인: 정사각형에 가까운 중앙 정렬 박스
기본 기능
- ✅ 인터랙티브 모드: 단계별 안내로 쉽게 카드 생성
- ✅ RGB 색상 입력: 사용자가 직접 RGB 값으로 색상 선택
- ✅ 한글 텍스트 완벽 지원
- ✅ 자동 중앙 정렬 및 레이아웃
- ✅ 600x600 Instagram 최적화
- ✅ 다양한 이미지 크기
설치 방법
필수 패키지 설치
pip install Pillow --break-system-packages폰트 (V2)
V2부터는 Cafe24Ssurround 폰트가 스킬에 포함되어 있어 별도 설치가 필요 없습니다!
폰트 위치: skills/card-news-generator/fonts/Cafe24Ssurround-v2.0.ttf
만약 시스템 폰트를 사용하려면 (선택사항):
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y fonts-noto-cjk fonts-noto-cjk-extra
# macOS - 시스템 폰트 자동 감지 (AppleSDGothicNeo)파일 구조
card-news-generator/
├── SKILL.md # 스킬 메타데이터 및 사용 가이드
├── generate_card.py # 카드 생성 스크립트 (V2 - 배경 이미지 지원)
├── auto_generator.py # 자동 카드 생성 스크립트
├── interactive_generator.py # 인터랙티브 모드
├── fonts/ # V2: 번들 폰트
│ └── Cafe24Ssurround-v2.0.ttf
├── V2_FEATURES.md # V2 상세 가이드
└── README.md # 이 파일사용 예시
방법 1: 자동 생성 모드 (V2 - 권장) 🆕
옵션 A: 단색 배경
python auto_generator.py \
--topic "건강 습관" \
--bg-color "#f5f3ee" \
--text-color "#1a1a1a" \
--output-dir ./output \
--base-filename "health" << 'EOF'
1. 수분 섭취
하루 8잔 이상
물 마시기 습관
2. 규칙적 운동
주 3회 이상
30분 운동하기
3. 충분한 수면
하루 7-8시간
숙면 취하기
EOF옵션 B: 배경 이미지 사용 (V2 신기능) ⭐
1단계: 배경 이미지 준비
이미지를 폴더에 순서대로 저장:
my-images/
├── 1.png
├── 2.png
└── 3.png또는 숫자로 정렬:
backgrounds/
├── 01.jpg
├── 02.jpg
└── 03.jpg2단계: 카드 생성
python auto_generator.py \
--topic "서울 부동산" \
--output-dir ./output \
--base-filename "realestate" \
--image-folder ./my-images \
--overlay-opacity 0.6 << 'EOF'
1. 가격 상승세
2023년 대비
평균 15% 상승
2. 거래량 증가
전년 동기 대비
거래 건수 20% 증가
3. 향후 전망
금리 안정화로
안정세 예상
EOF주요 파라미터:
--image-folder: 배경 이미지 폴더 경로--overlay-opacity: 오버레이 불투명도 (0.0~1.0)0.3: 밝은 이미지0.6: 보통 이미지 (권장)0.8: 어두운 이미지
방법 2: 인터랙티브 모드
사용자가 단계별로 입력하는 방식:
python interactive_generator.py프롬프트에 따라 다음을 입력: 1. 제목 (여러 줄 가능, 빈 줄로 종료) 2. 내용 (여러 줄 가능, 빈 줄로 종료) 3. 배경색 RGB (예: 245,243,238) 4. 텍스트색 RGB (예: 26,26,26) 5. 카드 번호 (선택사항) 6. 파일명
방법 3: 단일 카드 직접 생성
단색 배경:
python generate_card.py \
--title "수분 섭취" \
--content "하루 8잔 이상\n물 마시기 습관" \
--bg-color "#f5f3ee" \
--text-color "#1a1a1a" \
--output ./output/card.png배경 이미지 (V2): 🆕
python generate_card.py \
--title "가격 상승세" \
--content "2023년 대비\n평균 15% 상승" \
--bg-image ./my-images/1.png \
--overlay-opacity 0.6 \
--output ./output/card.png파라미터 설명
필수 파라미터
--title: 카드의 메인 제목 (줄바꿈은\n사용)--content: 본문 내용 (줄바꿈은\n사용)--output: 저장할 파일 경로
선택 파라미터 (기본)
--bg-color: 배경색 (기본값:#F5F3EE)--text-color: 텍스트 색상 (기본값:#1A1A1A)--width: 이미지 너비 (기본값: 600)--height: 이미지 높이 (기본값: 600)--title-size: 제목 폰트 크기 (기본값: 48)--content-size: 본문 폰트 크기 (기본값: 28)
V2 추가 파라미터 🆕
--bg-image: 배경 이미지 파일 경로--overlay-opacity: 오버레이 불투명도 (0.0~1.0, 기본값: 0.5)--image-folder: 배경 이미지 폴더 경로 (auto_generator.py)- 텍스트가 배경 이미지 위에 반투명 박스 + 흰색 테두리로 표시됨
- 배경 이미지 사용 시 텍스트 색상 자동으로 흰색으로 변경
추천 배경색 (RGB 형식)
| 색상 이름 | RGB 값 | Hex 코드 | 용도 |
|---|---|---|---|
| 따뜻한 베이지 | 245,243,238 | #f5f3ee | 기본, 모든 주제 |
| 소프트 핑크 | 255,229,229 | #ffe5e5 | 부드러운 주제 |
| 민트 그린 | 224,244,241 | #e0f4f1 | 자연, 건강 |
| 라벤더 | 232,224,245 | #e8e0f5 | 감성, 힐링 |
| 피치 | 255,232,214 | #ffe8d6 | 따뜻함, 활력 |
| 스카이 블루 | 227,242,253 | #e3f2fd | 전문성, 신뢰 |
색상 입력 방법:
- 인터랙티브 모드: RGB 값 직접 입력 (예:
245,243,238) - 직접 명령어: Hex 코드 사용 (예:
#f5f3ee)
해결 방법
한글이 깨질 때
# 폰트 재설치
sudo apt-get install --reinstall fonts-noto-cjk
fc-cache -fvPIL 모듈 에러
pip install --upgrade Pillow --break-system-packages파일 저장 실패
- 출력 경로가 존재하는지 확인
- 쓰기 권한이 있는지 확인
- 절대 경로 사용 권장
V2 주요 변경사항 요약
디자인 개선
- ✨ 반투명 검은색 박스 + 흰색 테두리로 텍스트 영역 강조
- ✨ 정사각형에 가까운 컴팩트 박스 (캔버스의 65% 너비)
- ✨ 텍스트 중앙 정렬로 배경 이미지가 양쪽에 보임
기술 개선
- 📦 Cafe24Ssurround 폰트 번들 포함 (별도 설치 불필요)
- 🖼️ 배경 이미지 자동 크롭 및 리사이징 (600x600)
- 🎨 오버레이 불투명도 조절 가능 (0.0~1.0)
- 🤖 배경 이미지 사용 시 텍스트 색상 자동 흰색 전환
- 🔤 macOS/Linux 자동 폰트 감지
지원 형식
- 배경 이미지: JPG, JPEG, PNG, WebP, BMP
- 출력 형식: PNG (600x600 Instagram 최적화)
스킬 로드 방법
Claude Code에서 이 스킬을 사용하려면:
1. 스킬 디렉토리를 skills 폴더에 복사 2. Claude에게 요청: "card-news-generator 스킬을 사용해서 카드를 만들어줘" 3. V2 기능 사용: "배경 이미지를 넣어서 카드 뉴스 만들어줘"
더 알아보기
- V2_FEATURES.md: V2 상세 기능 가이드 및 트러블슈팅
- SKILL.md: 스킬 메타데이터 및 자동화 워크플로우
라이선스
MIT License
Card News Generator V2 - Background Image Features
What's New in V2
카드 뉴스 생성기 V2에서는 배경 이미지 기능이 추가되었습니다. 이제 단색 배경뿐만 아니라 실제 사진을 배경으로 사용할 수 있습니다.
Key Features
1. 배경 이미지 지원
- 폴더에 있는 이미지 파일을 카드 배경으로 자동 적용
- JPG, PNG, WebP, BMP 등 다양한 포맷 지원
2. 자동 크롭 및 리사이징
- 이미지를 600x600 크기로 자동 조정
- 가로세로 비율 유지하며 중앙 크롭
3. 다크 오버레이
- 텍스트 가독성을 위한 어두운 오버레이 자동 적용
- 불투명도 조절 가능 (0.0 ~ 1.0)
4. 자동 텍스트 색상 전환
- 배경 이미지 사용 시 텍스트가 자동으로 흰색으로 변경
Quick Start
1. 배경 이미지 준비
이미지를 순서대로 정렬된 이름으로 저장하세요:
my-images/
├── 01.jpg
├── 02.jpg
├── 03.jpg
├── 04.jpg
└── 05.jpg2. 카드 뉴스 생성
python auto_generator.py \
--topic "여행 팁" \
--output-dir ./output \
--base-filename "travel" \
--image-folder ./my-images \
--overlay-opacity 0.6 << 'EOF'
1. 짐 싸기
최소한으로
가볍게 여행하기
2. 현지 음식
맛집 찾는
나만의 방법
3. 교통수단
대중교통 활용
팁과 노하우
4. 숙소 예약
가성비 좋은
숙소 찾기
5. 안전 여행
여행 중
안전 체크리스트
EOF3. 결과 확인
생성된 카드 이미지:
travel_01.png- 배경: 01.jpg + "짐 싸기" 내용travel_02.png- 배경: 02.jpg + "현지 음식" 내용travel_03.png- 배경: 03.jpg + "교통수단" 내용travel_04.png- 배경: 04.jpg + "숙소 예약" 내용travel_05.png- 배경: 05.jpg + "안전 여행" 내용
Parameters Explained
--image-folder
배경 이미지가 들어있는 폴더 경로를 지정합니다.
--image-folder /path/to/images- 폴더 내 이미지는 알파벳/숫자 순으로 정렬되어 사용됩니다
- 카드 1번에는 첫 번째 이미지, 2번에는 두 번째 이미지가 적용됩니다
- 이미지 수가 카드 수보다 적으면 나머지는 단색 배경으로 생성됩니다
--overlay-opacity
배경 이미지 위에 적용할 어두운 오버레이의 불투명도를 설정합니다.
--overlay-opacity 0.6값 범위: 0.0 ~ 1.0
0.0: 오버레이 없음 (원본 이미지 그대로)0.3: 약한 오버레이 (밝은 이미지에 적합)0.5: 중간 오버레이 (기본값, 대부분의 이미지에 적합)0.6: 강한 오버레이 (어두운 텍스트가 필요한 경우)0.8: 매우 강한 오버레이 (매우 밝은 이미지)1.0: 완전히 검은색 (거의 사용하지 않음)
추천 값:
- 밝은 사진 (하늘, 눈, 해변):
0.6 ~ 0.7 - 보통 사진 (풍경, 인물):
0.5 ~ 0.6⭐ 추천 - 어두운 사진 (실내, 저녁):
0.3 ~ 0.5
Single Card Example
단일 카드에 배경 이미지를 적용하려면:
python generate_card.py \
--title "여행 팁" \
--content "최소한의 짐으로\n가볍게 여행하기" \
--bg-image ./my-images/01.jpg \
--overlay-opacity 0.6 \
--number 1 \
--output ./output/card_01.pngTips & Best Practices
이미지 선택
✅ 좋은 배경 이미지:
- 고화질 이미지 (최소 600x600px 이상)
- 중앙에 주요 피사체가 있는 이미지
- 색상이 균일하지 않고 다양한 이미지
- 컨트라스트가 좋은 이미지
❌ 피해야 할 배경 이미지:
- 저화질/흐릿한 이미지
- 텍스트가 들어간 이미지 (겹칠 수 있음)
- 너무 어두운 이미지 (오버레이 후 가독성 떨어짐)
- 복잡한 패턴의 이미지 (텍스트 읽기 어려움)
오버레이 조정
이미지가 너무 밝아서 텍스트가 잘 안 보인다면:
--overlay-opacity 0.7 # 더 어둡게이미지가 이미 어두워서 텍스트가 묻힌다면:
--overlay-opacity 0.3 # 더 밝게파일 이름 규칙
이미지 파일명은 정렬 순서가 중요합니다:
✅ 좋은 예:
01.jpg, 02.jpg, 03.jpg, ...
img_001.png, img_002.png, ...
a_photo.jpg, b_photo.jpg, c_photo.jpg❌ 나쁜 예:
1.jpg, 2.jpg, 10.jpg, 11.jpg # 정렬 순서가 1, 10, 11, 2가 됨
photo.jpg, image.jpg, pic.jpg # 순서를 알 수 없음Comparison: V1 vs V2
V1 (Solid Color Only)
python auto_generator.py \
--topic "주제" \
--bg-color "#f5f3ee" \
--text-color "#1a1a1a" \
--output-dir ./output- 단색 배경만 가능
- 색상 선택 제한적
- 빠른 생성 속도
V2 (With Background Images)
python auto_generator.py \
--topic "주제" \
--image-folder ./images \
--overlay-opacity 0.6 \
--output-dir ./output- 실제 사진을 배경으로 사용
- 더 풍부한 시각적 표현
- 자동 이미지 처리
- 약간 느린 생성 속도 (이미지 로딩 시간)
Troubleshooting
문제: 이미지가 로드되지 않습니다
원인: 이미지 폴더 경로가 잘못되었거나 지원하지 않는 포맷
해결: 1. 폴더 경로를 확인하세요 2. 지원 포맷 확인: .jpg, .jpeg, .png, .webp, .bmp 3. 파일 권한 확인
문제: 텍스트가 잘 보이지 않습니다
원인: 배경 이미지가 너무 밝거나 복잡함
해결: 1. --overlay-opacity 값을 높이세요 (0.7 ~ 0.8) 2. 더 단순한 배경 이미지를 선택하세요 3. 이미지를 직접 어둡게 편집 후 사용하세요
문제: 이미지 순서가 이상합니다
원인: 파일명 정렬 순서 문제
해결: 1. 파일명을 01.jpg, 02.jpg 형식으로 변경 2. 앞에 0을 붙여서 정렬 보장 (예: 01, 02, ... 10, 11)
문제: 이미지가 잘립니다
원인: 이미지의 가로세로 비율이 정사각형이 아님
해결:
- 이것은 정상입니다. 600x600 정사각형으로 맞추기 위해 중앙을 기준으로 크롭됩니다
- 중요한 부분이 중앙에 오도록 이미지를 선택하거나 편집하세요
Examples Gallery
Example 1: Travel Cards
주제: 여행 팁 배경: 여행 사진 5장 오버레이: 0.6 결과: 밝고 생동감 있는 여행 팁 카드
Example 2: Food Cards
주제: 건강한 식습관 배경: 음식 사진 7장 오버레이: 0.5 결과: 식욕을 돋우는 건강 정보 카드
Example 3: Tech Cards
주제: 개발 팁 배경: 코드/컴퓨터 이미지 오버레이: 0.7 결과: 전문적인 느낌의 개발 팁 카드
Next Steps
1. 자신만의 이미지 폴더를 준비하세요 2. 다양한 --overlay-opacity 값을 테스트해보세요 3. 생성된 카드를 Instagram, Facebook 등에 공유하세요!
Feedback & Contribution
개선 사항이나 버그를 발견하시면 알려주세요!