component
TMC2262
Public Made by Adomby adom
Analog Devices TMC2262 65 V, 4 A RMS smart stepper driver with step/dir, SPI and encoder input, 30-pin FC2QFN 6x6. KiCad, Fusion and Altium libraries, datasheet-built 3D model, every pin cited to the data sheet.
main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
"""Component hero card in the existing wiki family (4000 x 2500): dark card, gradient top rule, COMPONENT eyebrow,
part number, category, maker and package, source footer, and the part render on the right over a soft glow."""
import math, os
import numpy as np
from PIL import Image, ImageDraw, ImageFilter, ImageFont
H = os.path.dirname(os.path.abspath(__file__))
FONTS = os.path.join(H, '..', 'fonts')
W, HH = 4000, 2500
BG = (13, 17, 23)
INK, INK2, INK3 = (236, 241, 245), (196, 204, 212), (122, 132, 143)
TEAL = (0, 214, 205)
def font(name, size):
return ImageFont.truetype(os.path.join(FONTS, name), size)
def fit(d, text, name, size, maxw):
while size > 60 and d.textlength(text, font=font(name, size)) > maxw:
size -= 6
return font(name, size)
def key_background(im, tol=4):
"""Make the renderer's flat backdrop transparent: pixels close to the corner colour AND connected to the border
(so dark parts of the component itself survive), with a soft 1 px edge. The backdrop is one exact colour
(64, 75, 85), so the match is tight: at 26 the grey end faces of 0603/1210 parts (68, 68, 66) were cut away too
and showed the page through them."""
from scipy import ndimage
a = np.asarray(im).astype(int)
bg = np.median(np.concatenate([a[0, :, :3], a[-1, :, :3], a[:, 0, :3], a[:, -1, :3]]), axis=0)
close = np.abs(a[..., :3] - bg).max(axis=2) <= tol
lab, n = ndimage.label(close)
edge = set(np.unique(np.concatenate([lab[0], lab[-1], lab[:, 0], lab[:, -1]]))) - {0}
mask = np.isin(lab, list(edge))
alpha = np.where(mask, 0, 255).astype('uint8')
alpha = np.asarray(Image.fromarray(alpha).filter(ImageFilter.GaussianBlur(0.8)))
out = im.copy(); out.putalpha(Image.fromarray(alpha))
return out
def make(render_png, out_png, title, subtitle, line, footer='Manufacturer datasheet · KiCad / LCSC CAD · Adom Wiki', eyebrow='COMPONENT',
box=(1550, 1500), center=(3080, 1300), text_w=2000):
img = Image.new('RGB', (W, HH), BG)
# soft teal glow behind the part
y, x = np.mgrid[0:HH // 4, 0:W // 4].astype(float)
g = np.exp(-(((x - 2900 / 4) / (900 / 4)) ** 2 + ((y - 1300 / 4) / (800 / 4)) ** 2))
glow = np.clip(np.array(BG, float) + g[..., None] * np.array([6, 38, 44], float), 0, 255).astype('uint8')
img.paste(Image.fromarray(glow).resize((W, HH), Image.BICUBIC))
d = ImageDraw.Draw(img)
# gradient top rule
for i in range(W):
t = i / W
c = tuple(int(a + (b - a) * t) for a, b in zip((0, 214, 205), (140, 107, 247)))
d.line([(i, 0), (i, 18)], fill=c)
# the part
part = key_background(Image.open(render_png).convert('RGBA'))
bb = part.getbbox()
if bb:
part = part.crop(bb)
s = min(box[0] / part.width, box[1] / part.height)
part = part.resize((int(part.width * s), int(part.height * s)), Image.LANCZOS)
img.paste(part, (center[0] - part.width // 2, center[1] - part.height // 2), part)
d = ImageDraw.Draw(img)
# text column
x0 = 230
d.text((x0, 420), ' '.join(eyebrow), font=font('JetBrainsMono-Medium.ttf', 64), fill=TEAL)
ft = fit(d, title, 'FamiljenGrotesk-Bold.ttf', 400, text_w)
d.text((x0, 560), title, font=ft, fill=INK)
tb = d.textbbox((x0, 560), title, font=ft)
y = tb[3] + 90
fs = fit(d, subtitle, 'Satoshi-Medium.otf', 120, text_w)
d.text((x0, y), subtitle, font=fs, fill=INK2)
y = d.textbbox((x0, y), subtitle, font=fs)[3] + 40
fl = fit(d, line, 'Satoshi-Medium.otf', 92, text_w)
d.text((x0, y), line, font=fl, fill=INK3)
d.text((x0, 2230), footer, font=font('JetBrainsMono-Regular.ttf', 56), fill=INK3)
img.save(out_png, optimize=True)
return out_png