from PIL import Image, ImageDraw, ImageFont, ImageChops from pathlib import Path R=Path(r'C:\projects\wheel\models\switch_2020_raise10_concept') def font(s):return ImageFont.truetype(r'C:\Windows\Fonts\msyh.ttc',s) def crop(name): im=Image.open(R/name).convert('RGB');bg=Image.new('RGB',im.size,'white');m=ImageChops.difference(im,bg).convert('L').point(lambda p:255 if p>15 else 0);b=m.getbbox();return im.crop(b) if b else im def paste(can,im,box): im.thumbnail((box[2]-box[0],box[3]-box[1]));can.paste(im,(box[0]+(box[2]-box[0]-im.width)//2,box[1]+(box[3]-box[1]-im.height)//2)) out=Image.new('RGB',(1900,1400),'#f4f7fb');d=ImageDraw.Draw(out) d.text((55,25),'灯光开关装配示意:中心轴整体上移 10 mm',font=font(40),fill='#1c2c40') d.text((58,87),'2020 横梁固定在 3030 纵梁上方;电机端增加 10 mm 支撑垫块。',font=font(23),fill='#3c526b') for x1,x2 in [(35,920),(950,1865)]:d.rounded_rectangle((x1,135,x2,915),radius=16,fill='white',outline='#d5dce5',width=2) d.text((55,149),'总装(灰色为型材,蓝色为电机侧垫块)',font=font(23),fill='#25384d');d.text((970,149),'开关局部(A 左、B 右)',font=font(24),fill='#25384d') paste(out,crop('assembly.png'),(55,190,900,890));paste(out,crop('switch_front.png'),(970,190,1845,885)) d.rounded_rectangle((35,945,1865,1360),radius=16,fill='white',outline='#d5dce5',width=2) d.text((60,967),'当前是尺寸方案,真实开关仍需实物核对',font=font(28),fill='#a12e1e') lines=[ 'A / B 比轴心分别低 35 / 22 mm;孔距 85 mm;孔组左右对称仅为示意假设。', '橙色:开关角码;红色:型材角码;绿色:开关估计包络,非真实外壳。', '横梁与估计包络无实体相交,最小距离 5 mm;开关角码仍穿入估计包络。', '若 A 到边缘的 7 mm 位于正下方,该处边缘与横梁顶面间约 3 mm;方向未确认。', '型材槽、全部螺栓与真实安装耳未完整建模;承载、实际装配和工具空间尚需核验。'] for i,line in enumerate(lines):d.text((60,1020+60*i),line,font=font(22),fill='#31485e') out.save(R/'开关2020横梁_轴心上移10_装配示意.png')