图片处理¶
有时我们需要反复绘制一个复杂的图形。如果每次我们都从头开始绘制,显然费时费力。更好的解决方法是先把它单独绘制到一个图片(Image)上,然后重复使用该图片进行绘制。
创建和绘制图片¶
使用create_image()函数来创建一个新的图片对象。
有两种方法来在图片上绘制图形:
- 面向对象方式:使用图片对象的成员方法。create_image()创建的是一个图片对象。我们可以直接使用它的成员方法。
img=create_image(800,600)
img.draw_circle(100,100,50)
- 传统方式:使用前面章节中的绘图函数,同时指明在哪个图片上绘制(缺省在绘图窗口中绘制)
img=create_image(400,300)
draw_circle(100,100,50,img)
绘图窗口和绘制目标(target)¶
在Easy Graphics中,绘图窗口就是一个特殊的图片。
为了减少编写程序的难度,Easy Graphics系统内部包含一个“绘制目标”属性。大多数绘图函数都有一个缺省的”image”或”dst_image”参数,如果未提供该参数,就会在系统的“绘制目标”上绘图。缺省的绘制目标就是绘图窗口。
所以,如果你没有修改过系统的“绘制目标”,在调用绘图函数时也没有指明在哪儿绘制,图形就会被绘制在绘图窗口里。
可以使用set_target()函数来改变系统的“绘图目标”,以及使用get_target()函数来获取当前的绘图目标。
下面的代码使用set_target()函数来将系统的“绘图目标设置”为一个图片, 然后在上面绘图:
注意:使用close_image()函数来关闭用完的图片。
img=create_image(400,300)
set_target(img)
draw_circle(100,100,50)
保存图片¶
可以使用save_image()函数来将图片保存到文件中。
下面的程序绘制一辆公共汽车,并将其保存到当前文件夹的”bus_screen.png”文件中。
注意,因为:
- save_image()缺省保存“绘制目标”图片;
- 缺省的“绘制目标”是绘图窗口。
因此我们保存到文件中的是绘图窗口中的内容。
from easygraphics import *
import draw_bus
def main():
init_graph(600,400)
draw_bus.draw_bus()
save_image("bus_screen.png")
pause()
close_graph()
easy_run(main)
复制图片¶
我们可以使用draw_image()函数来复制一个图片(或它的一部分)到另一张图片上。
在下面的例子中,我们将:
- 创建一个图片对象,保存到变量”img”中。
- 将“绘制目标”设为”img”。
- 在“绘制目标”(”img”图片)上画一辆公共汽车
- 将“绘制目标”设为绘图窗口
- 将”img”中的内容复制到绘图窗口的不同位置
from easygraphics import *
import draw_bus
def main():
init_graph(750, 450)
img = create_image(210, 130)
set_target(img) # set target to img
draw_bus.draw_bus()
set_target() # set target back to the graphics window
set_background_color("black")
for i in range(0, 9):
x = i % 3 * 250
y = i // 3 * 150
draw_image(x + 20, y + 10, img)
pause()
img.close()
close_graph()
easy_run(main)
结果:
图片透明和合成¶
put_image()从源图片复制一个矩形区域到目标图片上。如果你需要复制一个外形轮廓不是矩形的图像,可以先将其画在一个背景完全透明的图片上,然后再复制。
下面的例子中大部分代码和上一个例子相同,除了在画公共汽车之前,先把源图片的背景设成了透明。
from easygraphics import *
import draw_bus
def main():
init_graph(750, 450)
img = create_image(210, 130)
set_background_color(Color.TRANSPARENT, img) # set img's background to transparency
set_target(img) # set target to img
draw_bus.draw_bus()
set_target() # set target back to the graphics window
set_background_color("black")
for i in range(0, 9):
x = i % 3 * 250
y = i // 3 * 150
draw_image(x + 20, y + 10, img)
pause()
img.close()
close_graph()
easy_run(main)
结果是:
复制图片时忽略背景¶
如果你不喜欢使用透明背景,那么也可以在复制时将参数”with_background”设为False,这样在复制时将不会复制背景。
在下面的例子中,我们没有使用透明背景,而是直接不复制背景。
from easygraphics import *
import draw_bus
def main():
init_graph(750, 450)
img = create_image(210, 130)
set_target(img) # set target to img
draw_bus.draw_bus()
set_target() # set target back to the graphics window
set_background_color("black")
for i in range(0, 9):
x = i % 3 * 250
y = i // 3 * 150
draw_image(x + 20, y + 10, img, with_background=False)
pause()
img.close()
close_graph()
easy_run(main)
带几何变换的图片复制¶
如果你需要在复制图片的同时对其进行几何变换(如复制一张旋转后的图片),那你应该在复制前先在目标图片上设置变换。
下面的程序进行了旋转复制。请注意save_settings()和restore_settings()函数,它们被用来保存和恢复图片的设置(包括几何变换设置)。
注意:在变换和复制图片前先保存旧的设置,然后在复制完成后恢复原有设置是个非常好的习惯。
from easygraphics import *
import draw_bus
def main():
init_graph(750, 450)
img = create_image(210, 130)
set_target(img) # set target to img
draw_bus.draw_bus()
set_target() # set target back to the graphics window
set_background_color("black")
for i in range(0, 9):
x = i % 3 * 250 + 20
y = i // 3 * 150 + 10
save_settings()
# transforms
translate(x, y)
translate(105, 65)
rotate(45)
translate(-105, -65)
draw_image(0, 0, img, with_background=False)
restore_settings()
pause()
img.close()
close_graph()
easy_run(main)
读入图片文件¶
我们可以从文件中读入图片。
注意:JPEG格式图片不支持透明。因此如果你需要保存和载入带透明背景的图片,请使用PNG格式。
下面的例子从文件中读入图片,然后显示在绘图窗口中。
from easygraphics import *
def main():
init_graph(800, 600)
img = load_image("test.png")
draw_image((get_width() - img.get_width()) // 2,
(get_height() - img.get_height()) // 2, img)
pause()
img.close()
close_graph()
easy_run(main)
无窗口(headless)模式¶
有时我们只需要绘制和保存图片,并不需要在屏幕窗口上显示。为此,Easygraphics提供了无窗口(headless)模式,来完成这类工作。在该模式下,不显示绘图窗口,pause()、get_click()等为动画和交互服务的的函数也无法使用。
下面的程序展示了如何使用init_graph()函数进行无窗口模式。
from easygraphics import *
import draw_bus
def main():
init_graph(headless=True)
img = create_image(210, 130)
set_target(img)
draw_bus.draw_bus()
save_image("headless_bus.png")
img.close()
close_graph()
easy_run(main)