Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chiwa-kit

A complete Twitch channel visual identity, built in code. No graphics editor.

Seven stream screens, five channel panels, twelve emotes, six bit badges, thirteen channel-point icons and one seal — every piece is HTML/CSS or PIL geometry, rendered to PNG.

carousel


The pipeline

HTML + CSS  ──▶  Playwright (screenshot)  ──▶  PNG  ──▶  PIL (alpha work)  ──▶  final PNG

There is no image model anywhere in this. The shapes are hand-written SVG <path> data — one of the cats' bodies is literally this, in src/gatos.py:

CORPO = '''<path d="M56 53c-16.5 0-27 16.5-27 34 0 8 3 13.5 8.5 13.5h37C80 100.5 83 95 83 87c0-17.5-10.5-34-27-34z"/>
<circle cx="56" cy="42" r="23.5"/>'''

Four things worth reading

1. Keylines by alpha dilation · src/emotes.py, src/gatos.py

A Twitch emote has to stay legible on both the light and the dark theme. The fix is a keyline derived from the artwork's own alpha channel: dilate, blur, threshold, then composite a solid-colored mask behind the original piece.

gros = a.filter(ImageFilter.MaxFilter(7)) \
        .filter(ImageFilter.GaussianBlur(.7)) \
        .point(lambda v: 255 if v > 90 else 0)
back = Image.new('RGBA', im.size, (27,27,27,255)); back.putalpha(gros)
out  = Image.alpha_composite(back, im)

Light pieces get a dark keyline. Dark pieces (the cats) get a bone keyline plus a thin dark line outside it — two dilations at different radii, stacked.

2. Real holes, not black rectangles · src/build.py

Where gameplay or webcam goes, the overlay doesn't paint a black rectangle — it has alpha zeroed out. Render opaque, then punch.

def punch(path, rects):
    im = Image.open(path).convert('RGBA'); px = im.load()
    for (x, y, w, h) in rects:
        for j in range(y+1, y+h-1):
            for i in range(x+1, x+w-1):
                px[i, j] = (0, 0, 0, 0)
    im.save(path)

3. Die-cut with a paper sliver · src/diecut.py

Sticker-style contour cutting: a flood fill seeded from the outer border isolates only the exterior background (so interior whites survive), the silhouette is then dilated to leave a ~5px "paper" border, and a largest-connected-component BFS drops stray fragments.

4. Moon phases by circle subtraction · src/badges.py

The bit badges aren't drawn. They're two circles subtracting each other, supersampled 8× so they survive being displayed at 18 pixels.


Running it

npm install
pip install -r requirements.txt
playwright install chromium

python src/emotes.py      # 9 subscriber emotes
python src/gatos.py       # bit-tier emotes
python src/cafe.py
python src/badges.py      # bit badges
python src/icones.py      # channel-point icons
python src/icones2.py     # the three default-reward icons
python src/selo.py        # the seal
python src/assets.py      # packs everything into assets.json
python src/build.py       # the 7 stream screens
python src/hires_bits.py  # hi-res bit emotes used by the carousel
python src/carrossel.py   # the 11-slide brand manual

Paths are resolved from the file's own location (src/kitpath.py), so the scripts run from any folder on any OS — no editing, no sed. Playwright still needs a file:// URL for the local fonts; uri() builds a valid one on Windows, macOS and Linux.


Glossary

The channel is Brazilian, so identifiers and palette names are in Portuguese:

term meaning
osso / tinta bone (off-white) / ink (near-black)
vinho wine — the single accent color
grao grain (the noise overlay)
moldura frame
selo seal / sigil
contorno, gros, fora keyline; the inner and outer dilations
telas the full-screen states (starting / away / ended)
diecut, rasgado contour cut; torn-paper edge

What isn't here

One of the panels used third-party illustration. It was removed from this public repository — src/pain3.py renders an empty frame in its place. The plan is to commission an illustrator once the channel pays for itself.


On AI

This code was written with AI (Claude), under human direction: brief, references, brand, tone, vetoes, and a verdict on every iteration.

No image generator was used at any stage. There is no artist's illustration in here and nothing was copied. What exists is geometry written as code, coordinate by coordinate — and it's all open to inspect.

Reverse image search will turn up "similar": a sitting black cat exists in ten thousand cliparts, a rabbit inside an inverted triangle is centuries-old occult iconography, a crescent moon is a crescent moon. That's visual convention — the same reason every trash-can icon looks like every other trash-can icon. The proof isn't in an image search. It's in the code, which shows each shape being constructed from nothing.


License

Code: MIT. Brand and visual pieces: all rights reserved. You want the method, it's yours. You want the rabbit, it isn't. See LICENSE.


Made by @bnuuyCode · twitch.tv/heychiwa

About

My Twitch channel's entire visual identity, built in code with Claude AI — no graphics editor, no image generation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages