deploy(watermark-specific): 🚀 Update watermarked preview images and watermarking scripts for deployment
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
d1f1d62ed7
commit
aa336cd096
8 changed files with 167 additions and 4 deletions
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 189 KiB |
70
tooling/scripts/watermark/preview_bc.py
Normal file
70
tooling/scripts/watermark/preview_bc.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"""
|
||||
B vs C, fairly matched: dual-corner (C) vs edge-rail with a stronger plate (B+)
|
||||
to address the legibility hit Quinn flagged. Rendered on busy + bright.
|
||||
|
||||
Output: public/photos-watermarked/_preview/bc/
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from watermark_lib import WatermarkStyle, render_watermark, FONT_DIR
|
||||
|
||||
REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
||||
PUB = os.path.join(REPO, "deployments/@domains/quinn.www/root/public/photos")
|
||||
OUT = os.path.join(PUB + "-watermarked", "_preview", "bc")
|
||||
CARD_W = 380
|
||||
|
||||
SAMPLES = [
|
||||
("busy", f"{PUB}/quinn-pink-bra-boots-mural.jpeg"),
|
||||
("bright", f"{PUB}/quinn-nude-bed-frontal.jpeg"),
|
||||
]
|
||||
MODES = [
|
||||
("C: dual-corner", WatermarkStyle(mode="dual-corner", text_width_frac=0.34)),
|
||||
("B: edge-rail (orig)", WatermarkStyle(mode="edge-rail", rail_width_frac=0.46)),
|
||||
("B+: edge-rail solid plate", WatermarkStyle(mode="edge-rail", rail_width_frac=0.46,
|
||||
plate_alpha=215, plate_pad_frac=0.55)),
|
||||
]
|
||||
|
||||
|
||||
def label(im, text):
|
||||
bar = 24
|
||||
out = Image.new("RGB", (im.width, im.height + bar), (18, 18, 22))
|
||||
out.paste(im, (0, 0))
|
||||
try:
|
||||
f = ImageFont.truetype(os.path.join(FONT_DIR, "Audiowide-Regular.ttf"), 13)
|
||||
except Exception:
|
||||
f = ImageFont.load_default()
|
||||
ImageDraw.Draw(out).text((5, im.height + 5), text, fill=(255, 120, 190), font=f)
|
||||
return out
|
||||
|
||||
|
||||
def thumb(im, w=CARD_W):
|
||||
return im.resize((w, round(im.height * w / im.width)), Image.LANCZOS)
|
||||
|
||||
|
||||
def hstack(imgs, gap=12):
|
||||
h = max(i.height for i in imgs)
|
||||
out = Image.new("RGB", (sum(i.width for i in imgs) + gap * (len(imgs) - 1), h), (18, 18, 22))
|
||||
x = 0
|
||||
for i in imgs:
|
||||
out.paste(i, (x, 0)); x += i.width + gap
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
for sname, src in SAMPLES:
|
||||
im = Image.open(src)
|
||||
hstack([label(thumb(render_watermark(im, st)), ml) for ml, st in MODES]) \
|
||||
.save(os.path.join(OUT, f"{sname}__bc.jpg"), quality=94)
|
||||
print("written", OUT)
|
||||
for f in sorted(os.listdir(OUT)):
|
||||
print(" ", f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
88
tooling/scripts/watermark/preview_offfocal.py
Normal file
88
tooling/scripts/watermark/preview_offfocal.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"""
|
||||
Off-focal, crop-resistant candidates — keep the crisp corner look but park the
|
||||
mark off the subject and out of easy-crop range.
|
||||
|
||||
corner — reference (clippable)
|
||||
edge-rail — wordmark up a side margin at mid-height (auto-picks calmer side)
|
||||
dual-corner — top-left + bottom-right; one crop can't remove both
|
||||
|
||||
Output: public/photos-watermarked/_preview/offfocal/
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from watermark_lib import WatermarkStyle, render_watermark, FONT_DIR
|
||||
|
||||
REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
|
||||
PUB = os.path.join(REPO, "deployments/@domains/quinn.www/root/public/photos")
|
||||
OUT = os.path.join(PUB + "-watermarked", "_preview", "offfocal")
|
||||
CARD_W = 360
|
||||
|
||||
SAMPLES = [
|
||||
("busy", f"{PUB}/quinn-pink-bra-boots-mural.jpeg"),
|
||||
("bright", f"{PUB}/quinn-nude-bed-frontal.jpeg"),
|
||||
]
|
||||
MODES = [
|
||||
("corner (clippable)", WatermarkStyle(mode="corner", position="bottom-right")),
|
||||
("edge-rail (mid-height)", WatermarkStyle(mode="edge-rail", rail_width_frac=0.46)),
|
||||
("dual-corner", WatermarkStyle(mode="dual-corner", text_width_frac=0.34)),
|
||||
]
|
||||
|
||||
|
||||
def label(im, text):
|
||||
bar = 24
|
||||
out = Image.new("RGB", (im.width, im.height + bar), (18, 18, 22))
|
||||
out.paste(im, (0, 0))
|
||||
try:
|
||||
f = ImageFont.truetype(os.path.join(FONT_DIR, "Audiowide-Regular.ttf"), 13)
|
||||
except Exception:
|
||||
f = ImageFont.load_default()
|
||||
ImageDraw.Draw(out).text((5, im.height + 5), text, fill=(255, 120, 190), font=f)
|
||||
return out
|
||||
|
||||
|
||||
def thumb(im, w=CARD_W):
|
||||
return im.resize((w, round(im.height * w / im.width)), Image.LANCZOS)
|
||||
|
||||
|
||||
def hstack(imgs, gap=12):
|
||||
h = max(i.height for i in imgs)
|
||||
out = Image.new("RGB", (sum(i.width for i in imgs) + gap * (len(imgs) - 1), h), (18, 18, 22))
|
||||
x = 0
|
||||
for i in imgs:
|
||||
out.paste(i, (x, 0)); x += i.width + gap
|
||||
return out
|
||||
|
||||
|
||||
def crop_bottom(im, frac=0.18):
|
||||
return im.crop((0, 0, im.width, int(im.height * (1 - frac))))
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
for sname, src in SAMPLES:
|
||||
im = Image.open(src)
|
||||
hstack([label(thumb(render_watermark(im, st)), ml) for ml, st in MODES]) \
|
||||
.save(os.path.join(OUT, f"{sname}__modes.jpg"), quality=94)
|
||||
|
||||
im = Image.open(SAMPLES[0][1])
|
||||
corner = render_watermark(im, MODES[0][1])
|
||||
rail = render_watermark(im, MODES[1][1])
|
||||
dual = render_watermark(im, MODES[2][1])
|
||||
hstack([
|
||||
label(thumb(crop_bottom(corner)), "corner — bottom crop: GONE"),
|
||||
label(thumb(crop_bottom(rail)), "edge-rail — bottom crop: SURVIVES"),
|
||||
label(thumb(crop_bottom(dual)), "dual-corner — bottom crop: 1 SURVIVES"),
|
||||
]).save(os.path.join(OUT, "CROP_ATTACK.jpg"), quality=94)
|
||||
|
||||
print("written", OUT)
|
||||
for f in sorted(os.listdir(OUT)):
|
||||
print(" ", f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -24,10 +24,15 @@ FONT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fonts")
|
|||
|
||||
WATERMARK_TEXT = "transquinnftw.com"
|
||||
|
||||
# Kuromi palette
|
||||
PINK = (255, 46, 151) # electric hot pink — the wordmark fill
|
||||
PINK_GLOW = (255, 38, 138) # slightly deeper pink for the neon halo
|
||||
BLACK = (8, 8, 12) # near-black for stroke + plate
|
||||
# Kuromi palette — SHARED BRAND SOURCE OF TRUTH.
|
||||
# These MUST match the canonical hex in the provider-site theme tokens:
|
||||
# deployments/@domains/quinn.www/root/src/themes/kuromi-tokens.ts
|
||||
# (pink #FF2E97 → PINK, pinkGlow #FF268A → PINK_GLOW, black #08080C → BLACK)
|
||||
# This is Python with no cross-language import; keep the two in lockstep by
|
||||
# hand and update both when the brand palette changes.
|
||||
PINK = (255, 46, 151) # #FF2E97 — electric hot pink — the wordmark fill
|
||||
PINK_GLOW = (255, 38, 138) # #FF268A — slightly deeper pink for the neon halo
|
||||
BLACK = (8, 8, 12) # #08080C — near-black for stroke + plate
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue