众所周知, turtle模块由于使用简单, 是Python初学者中较受欢迎的模块之一。本文介绍如何使用PIL库实现turtle中的图片旋转效果。
如果前面看不懂,可以直接复制文章后面的代码。

目录

  • 使用PIL库
  • 实现图片旋转

使用PIL库

在Python中, 实现图片的旋转需要使用PIL库, 该库可通过pip安装。
使用PIL的Image.open函数可以实现加载图片; 使用ImageTk.PhotoImage可将PIL.Image对象转换为tkinter使用的类型。
由于 turtle模块与tkinter紧密结合,turtle的绘图依赖于tkinter实现,这里就需要用到tkinter。
PIL与tkinter实现的显示图片的程序如下:

from tkinter import *
from PIL import Image,ImageTk
root=Tk()
cv=Canvas(root,bg='black')
cv.pack(side=TOP,expand=True,fill=BOTH)
image=Image.open("bh.png","r")
image=image.resize((100,100))
imtk=ImageTk.PhotoImage(image)
id=cv.create_image(100,100,image=imtk)
cv.after(20,animate)root.mainloop()

效果图:

利用PIL.Image对象的rotate方法可实现图片的旋转。
有动画实现的代码:

from tkinter import *
from PIL import Image,ImageTkangle = 0
def animate():global angle,idangle += 10image=old.rotate(angle);imtk=ImageTk.PhotoImage(image)cv.delete(id)id=cv.create_image(100,100,image=imtk)cv.after(20,animate)root=Tk()
cv=Canvas(root,bg='black')
cv.pack(side=TOP,expand=True,fill=BOTH)
old=Image.open("blackhole.jpg","r").resize((100,100))
imtk=ImageTk.PhotoImage(old)
id=cv.create_image(100,100,image=imtk)
cv.after(20,animate)root.mainloop()
  • 为什么这里不加global imtk不能产生旋转的效果?
    在tkinter中, ImageTk.PhotoImage()对象必须被创建为一个引用, 否则对象的内存空间将被回收。因此, 应将ImageTk.PhotoImage()对象保存到一个列表或字典中, 或声明为全局变量(比如在这里)。
from tkinter import *
from PIL import Image,ImageTkangle = 0
def animate():global imtk,angle,id # 注意这行增加的imtkangle += 10image=old.rotate(angle)imtk=ImageTk.PhotoImage(image)cv.delete(id)id=cv.create_image(100,100,image=imtk)cv.after(20,animate)root=Tk()
cv=Canvas(root,bg='black')
cv.pack(side=TOP,expand=True,fill=BOTH)
old=Image.open("blackhole.jpg","r").resize((100,100))
imtk=ImageTk.PhotoImage(old)
id=cv.create_image(100,100,image=imtk)
cv.after(20,animate)root.mainloop()

效果图:

实现图片旋转

作者打开冗长的turtle模块的源代码, (读了半天)找到了TurtleScreenBase类, 用于底层的绘制图形等操作。程序的关键是使用自定义的函数替换turtle模块中原有的函数

完整代码如下(同学如果看不懂,可以直接复制粘贴到你的代码里面去):

from turtle import *
from turtle import TurtleScreenBase
try:from PIL import Image,ImageTk
except ImportError:Image=Noneimages={}
# 使用自定义的函数替换turtle模块中原有的函数
def _image(self,filename):img=Image.open(filename)im = ImageTk.PhotoImage(img)im.raw = imgim.zoomcache = [None,None]return imdef _createimage(self, image):"Create and return image item on canvas."id = self.cv.create_image(0, 0, image=image)return iddef _drawimage(self, item, pos, image, angle=None,zoom=None):"Configure image item as to draw image object at position (x,y) on canvas)"w=self.window_width();h=self.window_height()if not (-h//2 < pos[1] < h//2\and -w//2 <= -pos[0] < w//2):self.cv.itemconfig(item, image=self._blankimage()) # 清除图像returnprev=imageif zoom:# zoomcache为列表, 格式为[<放大倍数>, <图像>], 用于储存图像放大后的副本if zoom == image.zoomcache[0]:image=image.zoomcache[1]else:raw=image.rawsize=(int(raw.size[0] * zoom), int(raw.size[1] * zoom))raw = raw.resize(size,resample=Image.BILINEAR)image=ImageTk.PhotoImage(raw)image.raw=rawprev.zoomcache=[zoom,image]if angle is not None:raw=image.rawimage=ImageTk.PhotoImage(raw.rotate(angle))image.raw=rawimages[item]=image # 创建 img 的引用, 防止img消失x, y = posself.cv.coords(item, (x * self.xscale, -y * self.yscale))self.cv.itemconfig(item, image=image)def register_shape(self, name, shape=None):if shape is None:if name.lower()[-3:] in (".gif","jpg","bmp","png"):shape = Shape("image", self._image(name))else:raise TurtleGraphicsError("Bad arguments for register_shape.\n"+ "Use  help(register_shape)" )# 从turtle模块复制的部分elif isinstance(shape, tuple):shape = Shape("polygon", shape)## else shape assumed to be Shape-instanceself._shapes[name] = shape# turtle的_drawturtle方法, 当Turtle的形状将要绘制时调用
def _drawturtle(self):"""Manages the correct rendering of the turtle with respect toits shape, resizemode, stretch and tilt etc."""# 从turtle模块复制的部分screen = self.screenshape = screen._shapes[self.turtle.shapeIndex]ttype = shape._typetitem = self.turtle._itemif self._shown and screen._updatecounter == 0 and screen._tracing > 0:self._hidden_from_screen = Falsetshape = shape._dataif ttype == "polygon":if self._resizemode == "noresize": w = 1elif self._resizemode == "auto": w = self._pensizeelse: w =self._outlinewidthshape = self._polytrafo(self._getshapepoly(tshape))fc, oc = self._fillcolor, self._pencolorscreen._drawpoly(titem, shape, fill=fc, outline=oc,width=w, top=True)elif ttype == "image":# 形状为图像时screen._drawimage(titem, self._position, tshape,self.heading(),self._stretchfactor[0])elif ttype == "compound":for item, (poly, fc, oc) in zip(titem, tshape):poly = self._polytrafo(self._getshapepoly(poly, True))screen._drawpoly(item, poly, fill=self._cc(fc),outline=self._cc(oc), width=self._outlinewidth, top=True)else:if self._hidden_from_screen:returnif ttype == "polygon":screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")elif ttype == "image":screen._drawimage(titem, self._position,screen._shapes["blank"]._data)elif ttype == "compound":for item in titem:screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")self._hidden_from_screen = Trueif Image:TurtleScreenBase._image=_imageTurtleScreenBase._createimage=_createimageTurtleScreenBase._drawimage=_drawimageTurtleScreen.register_shape=register_shapeRawTurtle._drawturtle=_drawturtlescr=getscreen()
scr.register_shape('blackhole.jpg')
shape('blackhole.jpg')
while True:forward(60)left(72)
done()

运行效果:

Python turtle 实现图片旋转效果详解相关推荐

  1. python的turtle怎么设置rgb颜色_Python : turtle色彩控制实例详解

    ? 1 turtle.pencolor(* args ) 返回或设置pencolor. 允许四种输入格式: ? 1 pencolor() 将当前的pencolor返回为颜色规范字符串或元组(参见示例) ...

  2. python爬取图片-Python爬取网页中的图片(搜狗图片)详解

    前言 最近几天,研究了一下一直很好奇的爬虫算法.这里写一下最近几天的点点心得.下面进入正文: 你可能需要的工作环境: Python 3.6官网下载 本地下载 我们这里以sogou作为爬取的对象. 首先 ...

  3. python turtle库setpos_Python内置海龟(turtle)库绘图命令详解(二)

    继续谈利用海龟库(turtle库)做图.在这篇文章(Python内置海龟(turtle)库绘图命令详解(一))中已经介绍了turtle的一些基本画图命令,包括画布的设计.画笔属性与状态的设置以及画笔的 ...

  4. python编程入门与案例详解-quot;Python小屋”免费资源汇总(截至2018年11月28日)...

    原标题:"Python小屋"免费资源汇总(截至2018年11月28日) 为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29 ...

  5. Python 将.py转换为.exe详解

    本文是由@熊猫大哥大的博客修改而来(所以就不能说是"原创"了) 原博客链接:Python学习笔记(15)-Python代码转换为exe可执行程序详解(下面会提到本文与其的一点不同) ...

  6. 《 Python List列表全实例详解系列(三)》——列表添加元素(4种方法)

    < Python List列表全实例详解系列(三)> --列表添加元素(4种方法) 接上一篇:< Python List 列表全实例详解(二)>__访问列表元素(索引和切片)列 ...

  7. 《 Python List 列表全实例详解系列(九)》__列表反转(6种方法)

    < Python List 列表全实例详解系列(九)> __列表反转(6种方法) 本章目录: 十一.列表反转的6种方法 (11.1).通过列表的切片操作实现列表反转 (11.2).使用列表 ...

  8. python计算机二级操作题详解(一)

    python计算机二级操作题详解(一) **1. 1.仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留3位. 输入 该题目没有输入 ...

  9. 《 Python List列表全实例详解系列(二)》__创建列表(5种方式)

    < Python List列表全实例详解系列(二)> __创建列表(5种方式) 上一篇:< Python List 列表全实例详解系列(一)>__系列总目录.列表概念 本章目录 ...

最新文章

  1. 计算机二级C语言程序题常见题型,计算机二级C语言题型和评分标准
  2. 币圈老人李启元站队BCH,背后的原因是什么?
  3. CodeForces - 1337C Linova and Kingdom(贪心)
  4. 如何编写高性能的C#代码(二)
  5. JavaScript学习随记——数组一
  6. linux中安装jdk安装(rpm安装)
  7. dijkstra算法_最短路径问题——迪杰斯特拉算法(Dijkstra)
  8. 链表中倒数第 k 个节点
  9. H3C Private VLAN(私有vlan) 实验
  10. 拓端tecdat|用Prophet在Python中进行时间序列预测
  11. 查 oracle 的sid,oracle 查询sid 运行的sql语句
  12. android studio gjson,Android Studio插件GsonFormat
  13. 关于在networkx中使用louvain算法报错的问题
  14. 人工智能 7.专家系统
  15. python官网下载非常慢解决方法
  16. 学习《恋上数据结构与算法》目录索引 (持续更新中)
  17. 计算机应用能力考试湖南成绩查询,湖南计算机等级考试成绩查询入口
  18. 水溶性ZnCdS/ZnS量子点蓝光PL400nm-480nm
  19. 专访《突破》作者刘朋:程序员快速提升领导力的15个模式!
  20. 包机制 java (来自秦疆老师的视频学习)

热门文章

  1. 哪一类人适合做国外LEAD
  2. python中数组元素引用_python数组
  3. 抖音视频内容如何被快速推荐的几种方法:国仁楠哥
  4. MPU6050电路自检失败解决方案
  5. 判断字符串是否是回文(C语言)
  6. python 下标 遍历列表_python 遍历列表提取下标和值的实例
  7. 618入耳式无线蓝牙耳机哪款好,音质最好蓝牙耳机推荐
  8. java 内省源码_java 内省
  9. python的svm库_[Python] 机器学习库 Scikit-learn之SVM
  10. H5分享链接,禁止微信浏览器放大字体导致排版错乱不适配问题