DEV Community

weiwuji
weiwuji

Posted on

Automate Your Blog Images: Pillow Architecture Diagrams + Doubao API Banners

Automate Your Blog Images: Pillow Architecture Diagrams + Doubao API Banners

The Pain: The article is written, but the images aren't done — so you either spend half an hour drawing them by hand, or grab whatever picture you can find and call it a day. Every post needs images, and for a one-person company every hour spent in design software is an hour stolen from the actual work.
What You'll Learn:

  • The 4-step image pipeline: Pillow diagram → Doubao banner → WeChat asset library → embed in the article
  • A 100-line Pillow script that draws a consistent 4-layer architecture diagram in under a second — including the font-path trap that silently produces empty boxes
  • How to generate a banner with one Doubao API call — and why the model parameter takes an Endpoint ID, not a model name
  • The exact upload and embed format WeChat requires (data-src, rich_pages wxw-img, mmbiz.qpic.cn) — get it wrong and the release gate blocks your article

1. How You Make Article Images Today

For most people, the article-image routine looks like this:

Open PPT/PS -> draw boxes + arrows -> export image -> open the WeChat editor
-> upload to asset library -> insert into article -> position is off -> redo
Enter fullscreen mode Exit fullscreen mode

Three images per article, and an hour is gone. For an OPC (one-person company) founder, time is the scarcest resource of all.

In the previous article of this series — The One-Person Editorial Department: An Automated Content Factory for Solo Builders — I built a complete content generation pipeline: topic planning, AI generation, quality gates, data feedback. The content side was solved. That is when the next bottleneck showed up: content exists, images don't.

So I built an image pipeline for myself. Architecture diagrams are drawn by a Pillow script, banners are generated with one Doubao API call, and both go straight into the WeChat asset library. Today I'm going to open it up for you.

image pipeline: Pillow script draws the architecture diagram and the Doubao API generates the banner, both upload into the WeChat asset library, then the image is embedded in the article HTML — the whole chain runs in 10 seconds
The image pipeline: Pillow draws the architecture diagram, Doubao generates the banner, both upload to the asset library, and the article embeds them.


2. Step 1: Generate Architecture Diagrams with Pillow

Architecture diagrams are the most common image type and the most automation-friendly: boxes, arrows, text, fixed positions, high repetition. The script below draws a complete architecture diagram in 100 lines:

from PIL import Image, ImageDraw, ImageFont

# Font (needs CJK support)
FONT = '/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc'
font = ImageFont.truetype(FONT, 15)
font_title = ImageFont.truetype(FONT, 18)

# Create the canvas
img = Image.new('RGB', (800, 400), (15, 23, 42))
draw = ImageDraw.Draw(img)

# Draw the layers (4-layer architecture)
layers = [
    (50,  "#3b82f6", "Content Layer", "AI content generation · Pipeline orchestration"),
    (130, "#8b5cf6", "Delivery Layer", "Automated content factory · quality gate"),
    (210, "#06b6d4", "Service Layer", "Smart customer service · auto responses"),
    (290, "#10b981", "Growth Layer", "Data-driven · A/B testing"),
]
for y, color, title, desc in layers:
    draw.rounded_rectangle((60, y, 740, y+65), 8, fill=color)
    draw.text((400, y+10), title, fill="white", font=font_title, anchor="mt")
    draw.text((400, y+38), desc, fill="#dbeafe", font=font, anchor="mt")

img.save("architecture.png")
Enter fullscreen mode Exit fullscreen mode

Three things happen in this code:

  1. Create the canvas: 800×400 pixels, dark background
  2. Draw the boxes: rounded_rectangle draws each layer
  3. Write the text: text labels the name and description

✅ Verified: the script finishes and outputs the image in under a second.

4-layer architecture diagram drawn by the Pillow script: content layer, delivery layer, service layer, growth layer — each a colored band with a name and description, on a dark canvas
architecture.png — what the script draws: four layers, one consistent style, regenerated any time.

🩸 Pitfall: the font path is the biggest trap. On servers, the Noto Sans CJK font may live under opentype/noto/ instead of truetype/noto/. When the CJK path is wrong, Pillow does not raise an error — the text just renders as empty boxes. Run find /usr/share/fonts -name "*.ttc" first to confirm the path, then write the script.

💼 Value: the same script produces a consistent style every single time. Want a new layer? Change one line of code — no need to reopen design software.

Cognitive leap: making images is not design work, it's programming work. The moment you turn "drawing pictures" into "running a script", it automates itself.


3. Step 2: Generate a Banner with One Doubao API Call

Covers and banners need design sense and visual punch — Pillow is the wrong tool. This is where the Doubao text-to-image model on Volcano Engine comes in.

One command, one banner:

curl -s "https://ark.cn-beijing.volces.com/api/v3/images/generations" \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{
    "model":"ep-YOUR_ENDPOINT_ID",
    "prompt":"a tech-style WeChat article cover, deep blue background, clean geometric lines, whitespace in the top-left corner for the title",
    "n":1,
    "size":"1920x1920"
  }'
Enter fullscreen mode Exit fullscreen mode

The response contains a download URL. Grab the image and upload it to the WeChat asset library.

Key parameters:

  • model: not the model name, but the Endpoint ID you create in the Volcano Engine console (format ep-2026xxxxxxxx-xxx)
  • size: minimum 1920×1920 (3.68 megapixels — anything smaller returns an error)
  • prompt: plain language is enough; describe the visual style and where you want the whitespace

✅ Verified: I ran this exact command in front of you; the returned image URL opens in a browser for preview.

Doubao banner flow: one curl call with a prompt and endpoint ID goes into the Ark API, the JSON response returns an image download URL, and if you are not satisfied you change the prompt and rerun at zero cost — plus the pitfall that model takes an Endpoint ID, not the model name
The Doubao banner flow: one curl call in, one image out — and the one parameter that trips everyone up.

🩸 Pitfall: the Endpoint ID is not the model name. Plenty of people pass doubao-seedream-5-0 as the model parameter and get "model not found". Create an endpoint in the Volcano Engine console first, then put the returned ep-xxxx into the model field.

💼 Value: hiring a designer for a cover used to start at 200 yuan. One curl call now does it. Not satisfied? Change the prompt and run again — zero cost.

Cognitive leap: "design" is moving from a human skill to an API call. You don't need to know design — you need to know how to describe.


4. Step 3: Upload Everything to the WeChat Asset Library

Both image types — the PNG from Pillow and the JPG from Doubao — walk through the same upload flow:

import urllib.request, json

# Get the access token
url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" \
      f"&appid={APP_ID}&secret={APP_SECRET}"
token = json.loads(urllib.request.urlopen(url).read())["access_token"]

# Upload the image to the asset library
url = f"https://api.weixin.qq.com/cgi-bin/material/add_material" \
      f"?access_token={token}&type=image"
# multipart upload of the image file...
# returns {"media_id": "xxx", "url": "https://mmbiz.qpic.cn/..."}
Enter fullscreen mode Exit fullscreen mode

The returned url is a WeChat CDN link (mmbiz.qpic.cn) that you can reference directly in the article body.


5. Step 4: Embed the Image (Critical — Wrong Format Gets Blocked)

Once the image is in the asset library, embedding it in the article HTML requires this exact format — no shortcuts:

<!-- Correct: passes the release gate -->
<img data-src="https://mmbiz.qpic.cn/mmbiz_png/xxxxx/640?wx_fmt=png" 
     class="rich_pages wxw-img" 
     style="width:100%;" />
Enter fullscreen mode Exit fullscreen mode

Three requirements, all mandatory:

  1. Use data-src instead of src — the canonical format the WeChat editor produces
  2. Add class="rich_pages wxw-img" — tells WeChat this is an article body image
  3. The image must live in the WeChat asset library — domain mmbiz.qpic.cn

The wrong format (the release gate replies "illegal image link"):

<img src="http://example.com/my-image.png" />
Enter fullscreen mode Exit fullscreen mode

🩸 Pitfall: I stepped on this landmine myself. Embedding with src= got my submission intercepted by WeChat's risk control at publish time, with the error "please do not insert illegal image links". Switching src to data-src and adding the class fixed it on the first retry.

embed format comparison: the correct format with data-src, class rich_pages wxw-img and a mmbiz.qpic.cn URL passes the release gate, while img src pointing at an external domain gets the article rejected with an illegal image link error
Correct vs. blocked: the three-requirement format that sails through the gate, next to the src= format that gets rejected.


6. Putting the Four Steps Together: One Command for the Whole Chain

The four steps chain into a single routine. Every day after writing an article, I run one command:

python3 gen_arch_diagram.py          # Pillow draws the architecture diagram
python3 gen_banner.py "topic prompt" # Doubao generates the banner
python3 upload_to_wechat.py          # upload to the asset library
Enter fullscreen mode Exit fullscreen mode

The whole process is automated: from 30 minutes of manual work down to 10 seconds.

✅ Verified: this article's images are the pipeline's output — the architecture diagram came from Pillow, the banner from Doubao, both uploaded to the WeChat asset library.

💼 Value: article + images = a complete deliverable. Readers aren't staring at bare text; they're reading a fully illustrated, hand-holding tutorial.

Cognitive leap: images are not an independent task — they are one step in the content pipeline. Put them in the pipeline and you never have to think about them again.


7. Where You Are Now

You are no longer the content creator who opens Photoshop and fiddles for half an hour to make one image. You are becoming a system builder who generates images with code and designs covers with an API.

In the next article, we'll put guardrails on this pipeline — making the Agent not just capable of doing the work, but incapable of getting it wrong.


🏷️ Entities: Pillow, Volcano Engine, Doubao, ImageMagick
💼 Value: image automation, content pipeline, OPC efficiency tools
🧠 Insight: from design to programming — images are engineering work, not creative work

About the author: Wu Ji (无记) — AI & digitalization practitioner focused on Agent engineering, Loop Engineering, and digital transformation. Practical, hands-on tutorials — follow along and it just works.

Top comments (0)