Community图像github.com

ChenKuan1110/daily-card

生成「每日一句 / 打卡」风格社交卡片图,适用于朋友圈、公众号、小红书。当用户要求做卡片图、日签、打卡图、语录海报、带标题+副标题+日期的分享图,或要调整主题配色/贴纸元素、从背景图自动取配色时使用。触发词:每日一句、打卡图、日签、分享图、朋友圈配图、小红书封面、公众号首图、卡片生成、daily card、社交卡片。

daily-card 是什么?

daily-card is a Claude Code agent skill that 生成「每日一句 / 打卡」风格社交卡片图,适用于朋友圈、公众号、小红书。当用户要求做卡片图、日签、打卡图、语录海报、带标题+副标题+日期的分享图,或要调整主题配色/贴纸元素、从背景图自动取配色时使用。触发词:每日一句、打卡图、日签、分享图、朋友圈配图、小红书封面、公众号首图、卡片生成、daily card、社交卡片。.

兼容平台✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/ChenKuan1110/daily-card/tree/HEAD

Installed? Explore more 图像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

daily-card · Social Card Generator

One-Liner

Input Title + Subtitle → Output a PNG: automatically includes today's date, vector stickers related to the text theme, and a unified color scheme. Purely local rendering, 100% control over Chinese text, reproducible results with the same parameters.

This repository is itself a skill directory: The directory containing this SKILL.md is the project root. Code, configuration templates, and documentation are all at the same level. It can be placed into the respective skills paths of WorkBuddy / Claude Code / Codex CLI, or imported by skillhub-like platforms from GitHub.

Installation & Location

Project root = Directory containing this SKILL.md. It can run from any path — the code uses __file__ for location, no absolute paths required.

cd /path/to/daily-card          # Replace with actual installation location
python3 -m pip install -r requirements.txt
./install.sh                    # Idempotent installation: dependencies, private config initialization, self-check
./scripts/selfcheck.sh          # Can run self-check independently anytime (also CI entry point)

No internet connection required, no AI interface, no API key needed. Chinese font auto-detection: macOS uses Hiragino Sans GB / PingFang, Linux uses Noto Sans CJK, Windows uses Microsoft YaHei; if none are found, it exits with a prompt to specify a font file using --font / --font-bold.

Agents should prioritize using the local CLI; no need to start any service. The web backend and remote API are optional and described in "Two Optional Backends".

Most Common Use: Command Line Generation (Preferred for Agents)

python3 cardgen.py "Live well today" "Make ordinary days a little brighter"

The command prints the full path after File: ...; present this PNG path to the user using present_files, and explain the theme and dimensions in the response. Default output directory is output/, filename is <Title>-<Date>-<Platform>.png.

Common Parameters

ParameterPurposeExample
-t / -sTitle / Subtitle-t "Good Morning" -s "Get up first"
--platformDimension presetxhs(1080×1440) / moments(1080×1080) / wechat(900×500) / story(1080×1920) / wechat2(1080×460)
--themeForce a theme; by default auto-detects from keywords--theme study
--dateSpecify date--date 2026-01-01
--brandFooter branding--brand "Claw · Daily Quote"
--outSpecify output path--out /tmp/card.png
--seedLayout random seed; same seed = same layout--seed 42
--bg-imageCustom background image (auto color extraction)--bg-image ./bg.jpg
--bg-schemeUse the Nth color scheme from the image, or a custom main color--bg-scheme 2 / --bg-scheme "#C2185B"
--list-schemesOutput the candidate color scheme JSON for the background imagepython3 cardgen.py --bg-image bg.jpg --list-schemes
--list-themesList all themes and stickers
--config-dirUse a different config directory
--init-configRebuild config/themes.json from the factory template (overwrites private themes; back up first)

Complete Workflow for Background Image Color Extraction

# 1. First, see which color schemes the image can extract (returns JSON: name / base / colors / ratio)
python3 cardgen.py --bg-image ./bg.jpg --list-schemes

# 2. Choose one to generate (0 is main color; 1/2/3 are accent colors; can also directly give #RRGGBB)
python3 cardgen.py "Dusk is the day's reply to the night" "Good work today" \
  --bg-image ./bg.jpg --bg-scheme 2 --platform xhs

All colors (background, text, accent, card, stickers) are derived from the selected scheme, so sticker colors are always in the same palette as the image; sticker type is still automatically matched based on the title theme.

Configuration Files (Edit Configs, Not Code)

FileContentVersion Controlled
config/themes.default.jsonFactory template: 11 theme sets, read-only, used for "restore defaults"Yes
config/stickers.json28 stickers' Chinese names/groups + 6 background pattern registrations (with semantic description desc)Yes
config/themes.jsonActive theme configuration: label, keywords, 10 colors, motif, stickers, darkNo, private data
config/settings.jsonDefault platform, branding, oversampling factor, grain intensity, output directory, default color scheme indexNo, private data

themes.json and settings.json are private user data, not in version control, not released with the public repository. On first run, cardconfig.ensure_config() automatically copies them from the factory template — no manual creation needed. To use a different config directory, use the DAILY_CARD_CONFIG environment variable or --config-dir. See config/README.md for details.

Built-in 11 themes: study morning night coffee sport nature mood work tech festival quote.

To change colors/stickers: Edit config/themes.json directly in the corresponding theme's colors / stickers / keywords, or use the web backend API; the script re-reads the file on every run, so changes take effect immediately. To add a new theme, include all 10 color keys (#RRGGBB) and at least one valid sticker ID. Because it's private data, changes won't appear in git status; back up by copying the file manually.

Two Optional Backends

BackendWhen NeededHow to Enable
None (default)Only using CLI to generate cardsDo nothing, just run python3 cardgen.py ...
Local Web Backend (standalone mode)Need GUI, real-time preview, visual theme editingpython3 server.py, serves both the page and API at http://127.0.0.1:8777
Remote Server (pure API mode)Team sharing, agent needs a stable endpointpython3 server.py --api-only + nginx subpath reverse proxy, set DAILY_CARD_URL

In --api-only mode, the backend only responds to /api/* (static files served directly by nginx); /api/reveal returns 403; GET /api/health returns version / mode / serves_static / config_dir for online version verification.

The CLI always runs on the caller's machine, independent of the backend. Do not call /api/* when no service is running — the connection will fail.

Local Web Backend (Visual Configuration + Real-Time Preview)

python3 server.py                 # http://127.0.0.1:8777 (standalone mode)
python3 server.py --port 9000 --open
python3 server.py --api-only       # Cloud deployment: only API, static served by nginx
# macOS: double-click start-server.command

Three panels: Card Design (form + real-time preview + download/save), Theme Configuration (visual color/sticker/keyword editing and writing back to JSON), Global Settings (defaults and rendering parameters). Tabs can be deep-linked via #design / #config / #settings.

The Theme Configuration panel has three columns: theme list / editor / real-time effect preview. When editing colors, background patterns, dark mode toggle, or stickers, the right side immediately shows the unsaved draft effect, including a real card, a color semiotics diagram (annotating what each of the 10 colors is used for and what the current pattern actually looks like), what the stickers look like under that color scheme, and WCAG contrast/brightness consistency diagnostics. The preview is read-only in memory — it does not write config/themes.json — save only when you click "Save Configuration".

Same-Domain Subpath Deployment (Cloud Server)

All frontend URLs are derived at runtime by web/app.js from BASE (document.baseURI), no hardcoded root paths in source; index.html uses relative paths for style.css / app.js. To point the API to a different domain, set window.DAILY_CARD_BASE before loading app.js. nginx strips /daily-card/api/* prefix to /api/* — no backend route changes needed.

CommandPurpose
./scripts/publish-web.shPublish web/ to a version directory and atomically switch the current symlink
./scripts/publish-web.sh --listView published versions and current symlink target
./scripts/publish-web.sh --rollback [ver]Instant rollback, no Python restart required
./scripts/test_subpath.pyIn-process simulation of nginx prefix stripping, 10-chain assertions

Frontend static versions can be released and rolled back independently of the backend. Use DAILY_CARD_WEB_ROOT (default /opt/daily-card-web) and DAILY_CARD_WEB_KEEP (default 5) to override. Trailing slash is mandatory: /daily-card must 301 redirect to /daily-card/, otherwise relative paths resolve to the domain root. Full nginx config, systemd, caching, and authentication details are in docs/DEPLOY.md.

When an agent calls the remote API, DAILY_CARD_URL must be set to the prefix (e.g., https://host/daily-card); the code will construct the full URL as https://host/daily-card/api/save — do not set it to the bare domain.

JSON API (Agents Can Call Directly, No Browser Needed)

EndpointDescription
GET /api/healthHealth check: version, running mode, config directory (no frontend required)
GET /api/bootstrapFetch themes_doc, settings, registry, platforms, and paths in one call
POST /api/renderGenerate a preview; returns {png: dataURL, path, theme, size, bytes}
POST /api/saveGenerate and write to output/; returns the saved path
POST /api/theme-previewUnsaved theme draft → card + semiotics diagram + sticker sheet + readability diagnostics; does not write config files
POST /api/schemesBackground image → multiple color schemes. Send {"path":"/abs/bg.jpg"} or {"image":"data:image/png;base64,..."}
GET /api/schemes?image_id=xxxRe-fetch schemes for a previously uploaded image
POST /api/config/themes{"themes_doc": {...}} save theme configuration (with validation)
POST /api/config/settings{"settings": {...}} save global settings
POST /api/config/resetRestore factory themes (overwrites private themes; back up first)
POST /api/revealOpen the output folder
GET /api/sticker?id=book&theme=studySticker icon PNG

Request body for /api/render and /api/save:

{
  "title": "Live well today",
  "subtitle": "Make ordinary days a little brighter",
  "platform": "xhs",
  "theme": "auto",
  "date": null,
  "brand": "Claw · Daily Quote",
  "seed": null,
  "bg_image_id": null,
  "bg_path": "./bg.jpg",
  "bg_scheme": 0,
  "dark_override": null
}
  • bg_scheme can be an integer index or #RRGGBB; dark_override as true/false forces light/dark card, null follows image detection.
  • bg_image_id is returned by /api/schemes; alternatively, bg_path can be a path accessible by the server.
  • The returned png is data:image/png;base64,... — decode and write to file.

Example (when DAILY_CARD_URL is not set, uses local):

DC_URL="${DAILY_CARD_URL:-http://127.0.0.1:8777}"
curl -s "$DC_URL/api/save" \
  -H 'Content-Type: application/json' \
  -d '{"title":"Live well today","subtitle":"Make ordinary days a little brighter","platform":"xhs"}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["path"])'

Theme Draft Preview / Color Diagnostics (Inspect Before Saving)

To evaluate a color scheme's appearance and text readability before writing the config, call /api/theme-preview. The theme field contains the complete theme draft, which the server only keeps in memory:

{
  "theme": {
    "label": "MY THEME · New Theme",
    "keywords": ["check-in"],
    "motif": "dots",
    "dark": false,
    "colors": {
      "bg1": "#F7E9C8", "bg2": "#EED6A4", "card": "#FFFCF6",
      "ink": "#2E3A2C", "sub": "#6D7570", "accent": "#E0703C",
      "accent2": "#5D8B6A", "soft": "#F1D9A8", "pill": "#2E3A2C",
      "pill_text": "#FFFDF5"
    },
    "stickers": ["book", "pencil", "sun"]
  },
  "title": "Sample Title",
  "subtitle": "Sample Subtitle",
  "platform": "moments",
  "date": "2026-11-11",
  "seed": 7
}

Returned fields (card / legend / stickers / sticker_sheet are all data:image/png;base64,...):

FieldMeaning
cardCard rendered from this draft
legendSemantic color scheme diagram: real pattern + card layers + what each of the 10 colors controls
stickersSelected stickers as they appear under the current color scheme
sticker_sheetFull sticker sprite, along with sheet (cols/rows/cell/order) for slicing and display
diagnostics[{level: ok/warn/tip, text: Chinese description}]
contrastContrast ratio values (ink_card / sub_card / pill_pair / card_bg / accent_bg / bg_light)
motif / dark / draft_onlyPattern Chinese name and description, light/dark flag, always true indicating unsaved

diagnostics checks WCAG contrast: readability of main text/subtext/label text, contrast between card and background, whether accent colors pop, and contradictions like "very dark background but set as light theme". Recommended workflow: First POST a draft to see diagnostics → if there's a warn, adjust colors based on hints and re-run → only call /api/config/themes to save when there are no warnings.

Without the backend, you can call the module directly:

import base64, cardconfig as cfg, cardpreview as cp
draft = cfg.load_doc()["themes"]["study"]        # Nested structure, includes colors
draft["colors"]["accent"] = "#C2185B"            # Make a change to test
r = cp.build_preview({"theme": draft, "title": "Sample", "subtitle": "Subtitle"})
for it in r["diagnostics"]:
    print(it["level"], it["text"])
open("/tmp/draft-card.png", "wb").write(base64.b64decode(r["card"].split(",", 1)[1]))

Updates & Multi-Sync

The single source of truth for versions is the git repository; all other endpoints are derivatives, with one-way flow:

EndpointUpdate MethodPrivate Config
Local machine / Cloud servergit pull && ./install.shUnaffected, not overwritten
Cloud server frontend static version./scripts/publish-web.sh, --rollback for instant rollbackDecoupled from Python service, no restart needed
Local skill registration./install.sh --link-skill creates symlink to avoid config driftUnaffected
Skillhub platform snapshotsMaintainer tags and re-imports; inherently version-laggedPlatform only gets factory template

The factory template themes.default.json is updated with versions; the user's private themes.json is never overwritten. To merge new factory themes into your own config, manually copy the relevant entries from themes.default.json, or use the backend's "Export JSON → Merge → Import" workflow. Do not run --init-config / /api/config/reset directly.

Server deployment and CI/CD instructions are in docs/DEPLOY.md. scripts/selfcheck.sh runs 8 steps, including frontend path portability checks and subpath deployment simulation (in-process proxy, no actual nginx required).

Agent Recommended Workflow

  1. Extract title and subtitle from user input (if no subtitle is given, generate a short, fitting phrase, or leave it empty).
  2. Determine platform: if unspecified, use xhs; if Official Account is mentioned, use wechat; for Moments, use moments.
  3. If the user provides a background image: first run --list-schemes or call /api/schemes to see candidates, then generate with the chosen scheme; if the user doesn't specify one, use scheme 0.
  4. Execute the CLI (no backend needed); only call /api/save when the user explicitly requests a backend/remote workflow.
  5. Use present_files to show the final image, and explain the theme, dimensions, date, and color scheme in your response.
  6. If the user wants to change the style: edit config/themes.json or use the backend config panel — do not edit cardgen.py.

Notes

  • Code division: cardgen.py handles rendering; cardconfig.py handles config loading/saving/color extraction; cardpreview.py handles theme draft previews and color diagnostics; server.py is the backend. All read the same config/*.json files.
  • output/, uploads/, config/themes.json, config/settings.json, and .env are all in .gitignore; examples/ contains demo images (~6.7 MB, not required for runtime, can be deleted at any time).
  • Theme IDs only allow alphanumeric characters, -, and _; colors must be #RRGGBB; sticker IDs must exist in config/stickers.json.
  • Larger image size and higher oversampling will slow down generation; default 2x oversampling is sufficient for clarity.
  • server.py has zero authentication and by default listens only on 127.0.0.1. Before public deployment, be sure to add reverse proxy authentication or IP whitelisting; for cloud deployment, use --api-only to expose only the API. See docs/DEPLOY.md for details.
  • Source code must not contain absolute paths like src="/..." / href="/..." / "/api/..."; selfcheck.sh will block such regressions. All requests should use url().

Known Limitations / Next Version Plans

  • Custom sticker upload is not supported (current version): Stickers can only be chosen from the 28 registered vector stickers in config/stickers.json. There is no separate sticker library management module, and uploading PNG/SVG as stickers is not supported. To add new shapes, developers currently need to add an s_xxx drawing function in cardgen.py and register it in stickers.json.
  • Next version plans: Custom sticker upload (PNG/SVG, with automatic color extraction to match themes), sticker library management panel (add/delete/edit/group/preview/reuse), and decoupling stickers from themes. This has been explicitly deferred to the next version by the user and is not included in this release.
  • Theme draft preview uses 1x oversampling for faster responses; the final 2x output may have slight differences in very fine details, but layout and color scheme are consistent.

相关技能