python 打印卷尺

python 打印卷尺

起因

想量一量?围,于是想买一个卷尺.要到?宝上买东西,就得看评论了,可是又有人说那家的卷尺有味道.于是就想自己自己做一个了.打印机其实是个挺好的工具,虽然不是3d打印机,但是2d的打印机打印2d的卷尺其实已经够用了.

经过

思路基本上就是,通过代码将直尺绘制在位图或矢量图上,之后通过图片或者pdf文档的方式打印出来,绘制的时候要注意尺寸比例.
出于编程复杂度方面的考量选择了位图并且直接打印图片的方式.
结果代码如下:

'''
The code generates an image ruler according to the configuration.
Then a printer is used to convert the image to a useable ruler.
'''

'''
Paper	mm	inches
A3	297 x 420 mm	11.7 x 16.5 inches
A4	210 x 297 mm	8.3 x 11.7 inches
A5	148.5 x 210 mm	5.8 x 8.3 inches
A6	105 x 148.5 mm  4.1 x 5.8 inches
'''

paper_sizes={
    'A3': (297,420),
    'A4': (210,297),
    'A5': (148.5,210),
    'A6': (105,148.5)
}

from PIL import Image,ImageDraw,ImageFont
import sys
import math
import json

# parse arguments

with open('config.json') as f:
    config=json.load(f)

paper_w,paper_h=paper_sizes[config['paper_type']]

k=config['precision']
ruler_w=config['ruler_w']
ruler_l=config['ruler_h']
ruler_start=config['ruler_start']
overlap_l=config['overlap_l']
scale_l=[3,2,1]
margin_top=10
margin_bot=10

font=ImageFont.truetype(config['font_file'],k*4)
# font=ImageFont.truetype(r'C:\Windows\Fonts\consola.ttf',k*5)

# checking and calculating

seg_l=paper_h-margin_top-margin_bot
# seg_l+n_seg*(seg_l-overlap_l)
n_seg=math.ceil((ruler_l-seg_l)/(seg_l-overlap_l))+1
seg_w=ruler_w
seg_margin=paper_w//n_seg-seg_w
if seg_margin<=0:
    print('Not enough space on paper!',file=sys.stderr)

im=Image.new('RGB',(paper_w*k,paper_h*k),(255,255,255))
draw=ImageDraw.Draw(im)

for i in range(n_seg):
    lux,luy=(seg_w+seg_margin)*i+seg_margin/2,margin_top
    # draw horizontal line
    draw.line((lux*k,0*k,lux*k,(im.height-margin_bot)*k),fill=(0,0,0))
    draw.line(((lux+seg_w)*k,0*k,(lux+seg_w)*k,(im.height-margin_bot)*k),fill=(0,0,0))
    seg_l=paper_h-margin_top-margin_bot
    seg_s=i*(seg_l-overlap_l)
    if seg_s+overlap_l>=ruler_l:
        break
    for j in range(seg_l):
        if seg_s+j>ruler_l:
            break
        if (seg_s+j)%10==0:
            sl=scale_l[0]
            # draw number
            s=str((seg_s+j)//10)
            size=font.getsize(s)
            draw.text(((lux+seg_w/2)*k-size[0]/2,(luy+j)*k-size[1]/2),s,fill=(0,0,0),font=font)
        elif (seg_s+j)%5==0:
            sl=scale_l[1]
        else:
            sl=scale_l[2]
        # draw scales
        draw.line((lux*k,(luy+j)*k,(lux+sl)*k,(luy+j)*k),fill=(0,0,0))
        draw.line(((lux+seg_w)*k,(luy+j)*k,(lux+seg_w-sl)*k,(luy+j)*k),fill=(0,0,0))

# draw paper border

draw.line((0*k+1,0*k+1,paper_w*k-1,0*k+1),fill=(0,0,0))
draw.line((paper_w*k-1,0*k+1,paper_w*k-1,paper_h*k-1),fill=(0,0,0))
draw.line((paper_w*k-1,paper_h*k-1,0*k+1,paper_h*k-1),fill=(0,0,0))
draw.line((0*k+1,paper_h*k-1,0*k+1,0*k+1),fill=(0,0,0))

# TODO: draw ruler start and end line

im.save('ruler.png')
{
    "paper_type": "A4",
    "precision": 10,
    "ruler_w": 15,
    "ruler_h": 2000,
    "overlap_l": 10,
    "font_file": "C:\\Windows\\Fonts\\consola.TTF",
    "ruler_start": 0,
    "scale_l": [3,2,1]
}
show: ruler.png
	ruler.png

ruler.png: ruler_gen.py
	python ruler_gen.py

clean:
	del ruler.png

当然是可以通过配置文件修改参数了,其实也就是使用PIL画了几条线而已,之后再添加一些数字.不过我觉得还挺好看,自己测试的时候是没问题的.其它的尺寸和参数也没有特别测试过.
result

结果

结果就是打印完之后还需要自己用裁纸刀才下来,如果需要保证耐用性,可以用胶带把它包裹起来(好累!).还有一个问题就是两次打印出来的结果刻度线的清晰程度不一样,不知道是不是我第二次没有打印原图的原因.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值