Python写春联(turtle版) |
您所在的位置:网站首页 › 新年咋画 › Python写春联(turtle版) |
Python就好比编程界的瑞士军刀,开箱即用、无所不能。这得益于Python简洁易用的语法,以及丰富的第三方库,你想在电脑上做什么,总能找到事半功倍的第三方库。比如,在这新春佳节之际,用Python来写个春联能做到吗?用Python自带的turtle库便可以实现。 ![]() turtle中的绘图是控制一只“小海龟”来实现的,海龟移动的路径便能形成图形。这种程序绘图的方式具有很强的可计算性,也涉及到许多数学几何知识。 turtle的海龟绘图很适合用来引导孩子学习编程。 最初来自于 Wally Feurzeig, Seymour Papert 和 Cynthia Solomon 于 1967 年所创造的 Logo 编程语言。 二、画春联背景春联背景的绘制比较简单,由于上下联、横批都是矩形,且颜色都是一致的。为了便于代码的复用,可以定义可以一个画背景的函数。如下所示: def drawChunLianBg(startX=0, startY=0, lenX=100, lenY=100): # 设置边框色和背景填充色 color('Yellow', 'OrangeRed') # 抬笔,定位起点 pu() goto(startX, startY) # 落笔,绘制春联矩形框,并填充颜色 pd() begin_fill() for i in range(2): fd(lenX) rt(90) fd(lenY) rt(90) end_fill() # 结束后抬笔 pu() 三、写字 方法一:write()函数直接写字关于写字,turtle提供了一个write()函数。 ![]() 优点:可以自定义汉字字体,写出漂亮的字体! 缺点:无法呈现书写字的动态效果。 turtle.write(arg, move=False, align='left', font=('Arial', 8, 'normal'))arg -- 要书写到 TurtleScreen 的对象 move -- True/False。 move 为真值,画笔会移至文本的右下角 align -- 字符串 "left", "center" 或 "right"。写到当前海龟位置。 font -- 一个三元组 (fontname, fontsize, fonttype) 以下是实现关键代码: def writeWord(target_word, startx, starty): # 基于坐标,打印单个汉字 color("black", "black") # 抬笔定位 pu() goto(startx,starty) pd() # 基于字体,打印汉字 write(target_word, move=False,align='left',font=('汉仪程行简',24, 'normal')) def writeWords(target_words, startx, starty,lineNum=1): # 打印多个汉字,lineNum控制每行的汉字数,默认为1 # 向右、向下的偏移量 right_shift = 0 down_shift = 0 # 遍历打印汉字 for word in target_words: writeWord(word, startx+right_shift*45, starty-down_shift*45) right_shift += 1 # 判断是否要换行 if right_shift % lineNum == 0: down_shift += 1 right_shift = 0在main()函数里直接调用drawChunLianBg和writeWords()就可以画出春联和写字啦。 def main(): initScreen() drawChunLianBg(-160, 215, 60, 500) writeWords(target_words="一往无前 奔赴星辰大海", startx=-145, starty=175) drawChunLianBg(90, 215, 60, 500) writeWords(target_words="保持热爱 静待春暖花开", startx=105, starty=175) drawChunLianBg(-110, 280, 210, 60) writeWords(target_words="虎虎生威", startx=-90, starty=230,lineNum=4) pu() goto(0, 0) done() 方法二:利用坐标“画”汉字如果要实现本文一开始的书写效果,思路便是要将汉字当作图形画出来。即需要知道每个汉字笔画中的关键坐标,让海龟根据坐标来移动,画出汉字。比如“万”这个字,我们可以这样来绘制: ![]() 也就是说,坐标越多,画出的汉字效果会越好。但可以想象这是一个非常繁琐、耗时的工作。本想放弃的我,在知乎发现了一位大神也做过类似的尝试,并且是利用Python爬虫实现了从网上获取中文字体笔画坐标。在本人感叹其精妙的代码后,本着没有必要重复造轮子的想法,本人最终决定copy核心代码试一试,没想到竟然成功了! 基本原理是这样的 ![]() 关键代码: def drawWords(target_words, startx, starty, lineNum=1): params = ( ('font', gen_url_encode_words(target_words)), ('shi_fou_zi_dong', '0'), ('cache_sjs1', '20031908'), ) # 发起网页请求 response = requests.get('https://bihua.51240.com/web_system/51240_com_www/system/file/bihua/get_0/', headers=headers, params=dict(params) ) content = response.content.decode('utf-8') # 解析每个字的笔画坐标 content = content.replace( 'hzbh.main(', '').split(');document.getElementById')[0] content = content.split('{')[-1].split("}")[0] pattern = re.compile(r'\w:\[(.+?)\]') result1 = re.split(pattern, content) words_order_list = {} words_cnt = 0 for r in result1: sec = re.findall(r'\'.+?\'', r) if len(sec): orders = sec[1].split('#') order_xy_routine = [] for order in orders: order_str = re.findall(r'\(\d+,\d+\)', order) order_xy = [eval(xy) for xy in order_str] order_xy_routine.append(order_xy) words_order_list['{}_{}'.format( words_cnt, target_words[words_cnt])] = order_xy_routine words_cnt += 1 setting() # 画布、画笔设置 right_shift = 0 down_shift = 0 for k, v in words_order_list.items(): for lines in v: pu() for xy in lines: x, y = xy x, y = x * 0.05 + startx + right_shift * 50, -y * 0.05 + starty - down_shift * 50 print(x, y) goto(x, y) pd() right_shift += 1 if right_shift % lineNum == 0: down_shift += 1 right_shift = 0![]() 利用write()写字注重生成的结果,效果更好;而利用坐标“画”字注重过程,是爬虫技术与海龟画图的完美合作,更有意思,让人不禁再次感叹Python的NB,每每这时总会想起那句至理名言——“人生苦短,我用Python!” 写在最后本文是围绕turtle库来构思写春联这件事的,其实用Python写春联远不止这一种方式。比如下面这副春联也是利用Python写的,简直太酷了。 ![]() 立个小小的flag,明年就来写这样的春联吧。(望不打脸😂) 最重要的话留在最后,祝大家虎年万事顺遂,保持热爱,奔赴星海! ![]() 关注公众号,回复“春联”,即可获取源代码! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |