Update: 2026-06-15 01:37:40
BIN
scratch/Roboto-Bold.ttf
Executable file
BIN
scratch/admin_base.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
BIN
scratch/admin_logo_final.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
scratch/admin_logo_test.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
88
scratch/compile_logos.py
Normal file
@@ -0,0 +1,88 @@
|
||||
import math
|
||||
import sys
|
||||
import os
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# Set font path to the local Roboto-Bold font
|
||||
font_path = 'scratch/Roboto-Bold.ttf'
|
||||
|
||||
def draw_gear(draw, cx, cy, r_out, r_in, teeth_count, teeth_h, teeth_w, color):
|
||||
draw.ellipse([cx - r_out, cy - r_out, cx + r_out, cy + r_out], fill=color)
|
||||
for i in range(teeth_count):
|
||||
angle = i * (2 * math.pi / teeth_count)
|
||||
x0 = cx + r_out * math.cos(angle)
|
||||
y0 = cy + r_out * math.sin(angle)
|
||||
tx = -math.sin(angle)
|
||||
ty = math.cos(angle)
|
||||
nx = math.cos(angle)
|
||||
ny = math.sin(angle)
|
||||
p1 = (x0 - (teeth_w/2) * tx, y0 - (teeth_w/2) * ty)
|
||||
p2 = (x0 + (teeth_w/2) * tx, y0 + (teeth_w/2) * ty)
|
||||
p3 = (x0 + teeth_h * nx + (teeth_w/3) * tx, y0 + teeth_h * ny + (teeth_w/3) * ty)
|
||||
p4 = (x0 + teeth_h * nx - (teeth_w/3) * tx, y0 + teeth_h * ny - (teeth_w/3) * ty)
|
||||
draw.polygon([p1, p2, p3, p4], fill=color)
|
||||
draw.ellipse([cx - r_in, cy - r_in, cx + r_in, cy + r_in], fill=(255, 255, 255, 255))
|
||||
|
||||
def draw_car_large(draw, color):
|
||||
# Center: (765, 205)
|
||||
# Cabin
|
||||
draw.polygon([(740, 155), (790, 155), (809, 198), (721, 198)], fill=color)
|
||||
# Windshield
|
||||
draw.polygon([(743, 161), (787, 161), (802, 194), (728, 194)], fill=(255, 255, 255, 255))
|
||||
# Windshield divider
|
||||
draw.rectangle([763, 161, 767, 194], fill=color)
|
||||
# Main body
|
||||
draw.polygon([
|
||||
(712, 195), (818, 195),
|
||||
(827, 204), (827, 246),
|
||||
(818, 255), (712, 255),
|
||||
(703, 246), (703, 204)
|
||||
], fill=color)
|
||||
# Headlights
|
||||
r_head = 9
|
||||
draw.ellipse([722 - r_head, 222 - r_head, 722 + r_head, 222 + r_head], fill=(255, 255, 255, 255))
|
||||
draw.ellipse([808 - r_head, 222 - r_head, 808 + r_head, 222 + r_head], fill=(255, 255, 255, 255))
|
||||
# Grille
|
||||
draw.rectangle([740, 222, 790, 232], fill=(255, 255, 255, 255))
|
||||
# Side mirrors
|
||||
draw.polygon([(694, 190), (703, 195), (703, 203), (694, 198)], fill=color)
|
||||
draw.polygon([(836, 190), (827, 195), (827, 203), (836, 198)], fill=color)
|
||||
|
||||
def create_app_logo(base_logo_path, text, output_path):
|
||||
im = Image.open(base_logo_path)
|
||||
draw = ImageDraw.Draw(im)
|
||||
color = (29, 32, 47, 255)
|
||||
|
||||
font_size = 90
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
# Get text bounding box
|
||||
bbox = draw.textbbox((0, 0), text, font=font)
|
||||
tw = bbox[2] - bbox[0]
|
||||
th = bbox[3] - bbox[1]
|
||||
|
||||
tx = 512 - (tw / 2)
|
||||
ty = 887 - (th / 2) - bbox[1]
|
||||
|
||||
draw.text((tx, ty), text, font=font, fill=color)
|
||||
im.save(output_path)
|
||||
print(f'Saved logo with text \"{text}\" to {output_path}. BBox: X={tx} to {tx+tw}, Y={ty+bbox[1]} to {ty+bbox[3]}')
|
||||
|
||||
# Create Admin logo
|
||||
print('Creating Admin Logo...')
|
||||
im_admin = Image.open('scratch/logo_s_only.png')
|
||||
draw_admin = ImageDraw.Draw(im_admin)
|
||||
color = (29, 32, 47, 255)
|
||||
draw_gear(draw_admin, cx=765, cy=205, r_out=52, r_in=20, teeth_count=8, teeth_h=16, teeth_w=20, color=color)
|
||||
im_admin.save('scratch/admin_base.png')
|
||||
create_app_logo('scratch/admin_base.png', 'ADMIN', 'scratch/admin_logo_final.png')
|
||||
|
||||
# Create Service logo
|
||||
print('Creating Service Logo...')
|
||||
im_service = Image.open('scratch/logo_s_only.png')
|
||||
draw_service = ImageDraw.Draw(im_service)
|
||||
draw_car_large(draw_service, color)
|
||||
im_service.save('scratch/service_base.png')
|
||||
create_app_logo('scratch/service_base.png', 'SERVICE', 'scratch/service_logo_final.png')
|
||||
|
||||
print('All logos compiled successfully.')
|
||||
48
scratch/draw_car.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
def draw_car_large(draw, color):
|
||||
# Center: (765, 205)
|
||||
# Scaled up by 1.25x for better visual weight
|
||||
|
||||
# 1. Cabin (upper part)
|
||||
# Trapezoid: top base from X=740 to 790, bottom base from X=721 to 809, Y=155 to 198
|
||||
draw.polygon([(740, 155), (790, 155), (809, 198), (721, 198)], fill=color)
|
||||
|
||||
# Windshield (white trapezoid inside cabin)
|
||||
draw.polygon([(743, 161), (787, 161), (802, 194), (728, 194)], fill=(255, 255, 255, 255))
|
||||
|
||||
# Vertical divider in windshield
|
||||
draw.rectangle([763, 161, 767, 194], fill=color)
|
||||
|
||||
# 2. Main body (lower part)
|
||||
# Polygon with cut corners: X=703 to 827, Y=195 to 255
|
||||
draw.polygon([
|
||||
(712, 195), (818, 195),
|
||||
(827, 204), (827, 246),
|
||||
(818, 255), (712, 255),
|
||||
(703, 246), (703, 204)
|
||||
], fill=color)
|
||||
|
||||
# 3. Headlights (white circles)
|
||||
r_head = 9
|
||||
draw.ellipse([722 - r_head, 222 - r_head, 722 + r_head, 222 + r_head], fill=(255, 255, 255, 255))
|
||||
draw.ellipse([808 - r_head, 222 - r_head, 808 + r_head, 222 + r_head], fill=(255, 255, 255, 255))
|
||||
|
||||
# 4. Grille / Bumper
|
||||
# Center grill: white rectangle from X=740 to 790, Y=222 to 232
|
||||
draw.rectangle([740, 222, 790, 232], fill=(255, 255, 255, 255))
|
||||
|
||||
# 5. Side mirrors
|
||||
# Left mirror: polygon at X=694 to 703, Y=190 to 202
|
||||
draw.polygon([(694, 190), (703, 195), (703, 203), (694, 198)], fill=color)
|
||||
# Right mirror: polygon at X=827 to 836, Y=190 to 202
|
||||
draw.polygon([(836, 190), (827, 195), (827, 203), (836, 198)], fill=color)
|
||||
|
||||
im = Image.open('scratch/logo_s_only.png')
|
||||
draw = ImageDraw.Draw(im)
|
||||
color = (29, 32, 47, 255)
|
||||
|
||||
draw_car_large(draw, color)
|
||||
im.save('scratch/service_logo_test_car_large.png')
|
||||
print("Saved large service logo to scratch/service_logo_test_car_large.png")
|
||||
44
scratch/draw_gear.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
def draw_gear(draw, cx, cy, r_out, r_in, teeth_count, teeth_h, teeth_w, color):
|
||||
# Draw outer body
|
||||
draw.ellipse([cx - r_out, cy - r_out, cx + r_out, cy + r_out], fill=color)
|
||||
|
||||
# Draw teeth
|
||||
for i in range(teeth_count):
|
||||
angle = i * (2 * math.pi / teeth_count)
|
||||
|
||||
# Center of tooth base on the outer radius
|
||||
x0 = cx + r_out * math.cos(angle)
|
||||
y0 = cy + r_out * math.sin(angle)
|
||||
|
||||
# Tangent vector for width
|
||||
tx = -math.sin(angle)
|
||||
ty = math.cos(angle)
|
||||
|
||||
# Normal vector for height
|
||||
nx = math.cos(angle)
|
||||
ny = math.sin(angle)
|
||||
|
||||
# 4 points of the tooth (trapezoid style: narrower at the tip)
|
||||
p1 = (x0 - (teeth_w/2) * tx, y0 - (teeth_w/2) * ty)
|
||||
p2 = (x0 + (teeth_w/2) * tx, y0 + (teeth_w/2) * ty)
|
||||
|
||||
p3 = (x0 + teeth_h * nx + (teeth_w/3) * tx, y0 + teeth_h * ny + (teeth_w/3) * ty)
|
||||
p4 = (x0 + teeth_h * nx - (teeth_w/3) * tx, y0 + teeth_h * ny - (teeth_w/3) * ty)
|
||||
|
||||
draw.polygon([p1, p2, p3, p4], fill=color)
|
||||
|
||||
# Draw inner cutout (hole)
|
||||
draw.ellipse([cx - r_in, cy - r_in, cx + r_in, cy + r_in], fill=(255, 255, 255, 255))
|
||||
|
||||
im = Image.open('scratch/logo_s_only.png')
|
||||
draw = ImageDraw.Draw(im)
|
||||
color = (29, 32, 47, 255)
|
||||
|
||||
# Draw gear at cx=765, cy=205
|
||||
draw_gear(draw, cx=765, cy=205, r_out=45, r_in=18, teeth_count=8, teeth_h=15, teeth_w=18, color=color)
|
||||
|
||||
im.save('scratch/admin_logo_test.png')
|
||||
print("Saved admin logo to scratch/admin_logo_test.png")
|
||||
51
scratch/draw_wrench.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import math
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
def draw_wrench(draw, color):
|
||||
# Centers
|
||||
cx_open, cy_open = 810, 160
|
||||
cx_closed, cy_closed = 720, 250
|
||||
|
||||
# Draw shaft
|
||||
# Direction vector from closed to open: (90, -90)
|
||||
# Unit vector: dx = 0.7071, dy = -0.7071
|
||||
# Perpendicular vector: px = 0.7071, py = 0.7071
|
||||
dx, dy = 0.7071, -0.7071
|
||||
px, py = 0.7071, 0.7071
|
||||
half_w = 12
|
||||
|
||||
p1 = (cx_closed - half_w * px, cy_closed - half_w * py)
|
||||
p2 = (cx_closed + half_w * px, cy_closed + half_w * py)
|
||||
p3 = (cx_open + half_w * px, cy_open + half_w * py)
|
||||
p4 = (cx_open - half_w * px, cy_open - half_w * py)
|
||||
|
||||
draw.polygon([p1, p2, p3, p4], fill=color)
|
||||
|
||||
# Draw open end outer circle
|
||||
draw.ellipse([cx_open - 38, cy_open - 38, cx_open + 38, cy_open + 38], fill=color)
|
||||
|
||||
# Draw closed end outer circle
|
||||
draw.ellipse([cx_closed - 30, cy_closed - 30, cx_closed + 30, cy_closed + 30], fill=color)
|
||||
|
||||
# Cut out the slot in open end (white polygon)
|
||||
# Slot of width 22, length 50, starting at cx_open, cy_open and going in direction (dx, dy)
|
||||
slot_half_w = 11
|
||||
s1 = (cx_open - slot_half_w * px, cy_open - slot_half_w * py)
|
||||
s2 = (cx_open + slot_half_w * px, cy_open + slot_half_w * py)
|
||||
s3 = (cx_open + 50 * dx + slot_half_w * px, cy_open + 50 * dy + slot_half_w * py)
|
||||
s4 = (cx_open + 50 * dx - slot_half_w * px, cy_open + 50 * dy - slot_half_w * py)
|
||||
draw.polygon([s1, s2, s3, s4], fill=(255, 255, 255, 255))
|
||||
|
||||
# Draw a small circle at the base of the slot to make it round and clean
|
||||
draw.ellipse([cx_open - 11, cy_open - 11, cx_open + 11, cy_open + 11], fill=(255, 255, 255, 255))
|
||||
|
||||
# Cut out closed end inner hole (white circle)
|
||||
draw.ellipse([cx_closed - 15, cy_closed - 15, cx_closed + 15, cy_closed + 15], fill=(255, 255, 255, 255))
|
||||
|
||||
im = Image.open('scratch/logo_s_only.png')
|
||||
draw = ImageDraw.Draw(im)
|
||||
color = (29, 32, 47, 255)
|
||||
|
||||
draw_wrench(draw, color)
|
||||
im.save('scratch/service_logo_test.png')
|
||||
print("Saved service logo to scratch/service_logo_test.png")
|
||||
BIN
scratch/logo_s_only.png
Normal file
|
After Width: | Height: | Size: 282 KiB |
BIN
scratch/service_base.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
BIN
scratch/service_logo_final.png
Normal file
|
After Width: | Height: | Size: 290 KiB |
BIN
scratch/service_logo_test.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
BIN
scratch/service_logo_test_car.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
BIN
scratch/service_logo_test_car_large.png
Normal file
|
After Width: | Height: | Size: 283 KiB |