在 PyCairo 教程的这个部分,我们将讨论剪裁和屏蔽操作。

剪裁

裁剪 是将绘制限定在某一区域内。这样做有一些效率的因素,或者为了创建有趣的效果。PyCairo 有一个 clip() 方法用于设置裁剪区域。

#!/usr/bin/python'''
ZetCode PyCairo tutorialThis program shows how to perform
clipping in PyCairo.author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import cairo
import math
import randomclass Example(Gtk.Window):def __init__(self):super(Example, self).__init__()self.init_ui()self.load_image()self.init_vars()def init_ui(self):self.darea = Gtk.DrawingArea()self.darea.connect("draw", self.on_draw)self.add(self.darea)GLib.timeout_add(100, self.on_timer)self.set_title("Clipping")self.resize(300, 200)self.set_position(Gtk.WindowPosition.CENTER)self.connect("delete-event", Gtk.main_quit)self.show_all()def load_image(self):self.image = cairo.ImageSurface.create_from_png("beckov.png")def init_vars(self):self.pos_x = 128self.pos_y = 128self.radius = 40self.delta = [3, 3]def on_timer(self):self.pos_x += self.delta[0]self.pos_y += self.delta[1]self.darea.queue_draw()return Truedef on_draw(self, wid, cr):w, h = self.get_size()if (self.pos_x < 0 + self.radius):self.delta[0] = random.randint(5, 9)elif (self.pos_x > w - self.radius):self.delta[0] = -random.randint(5, 9)if (self.pos_y < 0 + self.radius):self.delta[1] = random.randint(5, 9)elif (self.pos_y > h - self.radius):self.delta[1] = -random.randint(5, 9)cr.set_source_surface(self.image, 1, 1)cr.arc(self.pos_x, self.pos_y, self.radius, 0, 2 * math.pi)cr.clip()cr.paint()def main():app = Example()Gtk.main()if __name__ == "__main__":main()

在这个例子中,我们将裁剪一幅图片。一个圆圈在窗口区域移动,并显示下面的图片的一部分。这就好像我们通过一个洞看过去一样。

    def load_image(self):self.image = cairo.ImageSurface.create_from_png("beckov.png")

这是下面的图片。每一个定时器周期,我们将看到这幅图片的一部分。

        if (self.pos_x < 0 + self.radius):self.delta[0] = random.randint(5, 9)elif (self.pos_x > w - self.radius):self.delta[0] = -random.randint(5, 9)

如果圆圈击中了窗口的左边或右边,则圆圈移动的方向会随机地改变。对于上边和下边也一样。

        cr.arc(self.pos_x, self.pos_y, self.radius, 0, 2 * math.pi)

这一行给 Cairo 上下文添加一个圆形的 Path。

        cr.clip()

clip() 设置裁剪区域。裁剪区域是当前正在使用的 Path。当前的 path 由 arc() 方法调用创建。

        cr.paint()

paint() 用当前的 source 描绘当前裁剪区域内的部分。

屏蔽

在 source 被应用于 surface 之前,它首先会被过滤。mask 被用作一个过滤器。mask 决定 source 的哪个部分被应用,而哪个部分不会。mask 不透明的部分允许复制 source。透明的部分则不允许复制 source 到 surface。

#!/usr/bin/python'''
ZetCode PyCairo tutorialThis program demonstrates masking.author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import cairoclass Example(Gtk.Window):def __init__(self):super(Example, self).__init__()self.init_ui()self.load_image()def init_ui(self):darea = Gtk.DrawingArea()darea.connect("draw", self.on_draw)self.add(darea)self.set_title("Masking")self.resize(310, 100)self.set_position(Gtk.WindowPosition.CENTER)self.connect("delete-event", Gtk.main_quit)self.show_all()def load_image(self):self.ims = cairo.ImageSurface.create_from_png("omen.png")def on_draw(self, wid, cr):cr.mask_surface(self.ims, 0, 0);cr.fill()def main():app = Example()Gtk.main()if __name__ == "__main__":main()

在这个例子中,屏蔽决定了哪些地方需要绘制哪些地方不绘制。

        cr.mask_surface(self.ims, 0, 0);cr.fill()

我们使用一幅图片作为 mask,这将会把它显示在窗口中。

Blind down 效果

在这个代码例子中,我们将 blind down 我们的图片。这类似于我们使用的遮光窗帘。

#!/usr/bin/python'''
ZetCode PyCairo tutorialThis program creates a blind down
effect using masking operation.author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import cairo
import mathclass Example(Gtk.Window):def __init__(self):super(Example, self).__init__()self.init_ui()self.load_image()self.init_vars()def init_ui(self):self.darea = Gtk.DrawingArea()self.darea.connect("draw", self.on_draw)self.add(self.darea)GLib.timeout_add(35, self.on_timer)self.set_title("Blind down")self.resize(325, 250)self.set_position(Gtk.WindowPosition.CENTER)self.connect("delete-event", Gtk.main_quit)self.show_all()def load_image(self):self.image = cairo.ImageSurface.create_from_png("beckov.png")def init_vars(self):self.timer = Trueself.h = 0self.iw = self.image.get_width()self.ih = self.image.get_height()self.ims = cairo.ImageSurface(cairo.FORMAT_ARGB32,self.iw, self.ih)def on_timer(self):if (not self.timer):return Falseself.darea.queue_draw()return Truedef on_draw(self, wid, cr):ic = cairo.Context(self.ims)ic.rectangle(0, 0, self.iw, self.h)ic.fill()self.h += 1if (self.h == self.ih):self.timer = Falsecr.set_source_surface(self.image, 10, 10)cr.mask_surface(self.ims, 10, 10)def main():app = Example()Gtk.main()if __name__ == "__main__":main()

blend down 效果背后的想法相当的简单。图像有 h 个像素高。我们绘制 0,1, 2… 个 1 像素高的行。每个周期,图像的部分多出一像素的高度,直到整幅图片都变得可见为止。

    def load_image(self):self.image = cairo.ImageSurface.create_from_png("beckov.png")

load_image() 方法中,我们由一幅 PNG 图片创建一个图片 surface。

    def init_vars(self):self.timer = Trueself.h = 0self.iw = self.image.get_width()self.ih = self.image.get_height()self.ims = cairo.ImageSurface(cairo.FORMAT_ARGB32,self.iw, self.ih)

init_vars() 方法中,我们初始化一些变量。我们初始化 self.timerself.h 变量。我们获取所加载的图片的宽度和高度。然后我们创建一个空的图像 surface。它将会被来自于先前我们所创建的图像 surface 的像素行所填充。

        ic = cairo.Context(self.ims)

我们由空的图像 source 创建一个 cairo 上下文。

        ic.rectangle(0, 0, self.iw, self.h)ic.fill()

我们向最初为空的图像中绘制一个矩形。矩形每个周期高出 1px。用这种方式创建的图像将在后面作为一个 mask。

        self.h += 1

将要显示的图像的高度被加了一个单元。

        if (self.h == self.ih):self.timer = False

当我们在 GTK 窗口中绘制了整个图片时,我们停掉定时器方法。

        cr.set_source_surface(self.image, 10, 10)cr.mask_surface(self.ims, 10, 10)

城堡的图片被设置为绘制时的 source。mask_surface() 绘制当前的 source,使用 surface 的 alpha 通道作为一个 mask。

Blind down 是一种动画效果。

本章讨论了PyCairo中的裁剪和屏蔽。

原文

Done.

PyCairo 中的剪裁和屏蔽相关推荐

  1. PyCairo 中的图片

    PyCairo 教程的这个部分,我们将讨论图片.我们将演示如何在 GTK 窗口中显示一幅 PNG 或JPEG 图片.我们也将在图片上绘制一些文字. 显示一幅 PNG 图片 在第一个例子中,我们将显示一 ...

  2. PyCairo 中的文本

    PyCairo 教程的这个部分,我们将与文本打交道. 灵魂伴侣 在第一个例子中,我们将在窗口中显示一些歌词. def on_draw(self, wid, cr):cr.set_source_rgb( ...

  3. SQL Server中的动态数据屏蔽

    Security has been one of the prime concerns of database developers since the inception of database m ...

  4. azure云数据库_在Azure SQL数据库中实现动态数据屏蔽

    azure云数据库 In this article, we will review Dynamic Data Masking in the Azure SQL database. Dynamic Da ...

  5. 计算机电缆的铜丝和铜带的区别,电缆中,铜网屏蔽和铜带屏蔽的区别

    电缆中,铜网屏蔽和铜带屏蔽的区别 电缆中,铜网屏蔽好,还是铜带屏蔽好呢?让我们来了解下,屏蔽层主要起抗外界电磁干扰,防止使用过程中由于自身所产生的电磁场对周围环境的干扰和通故障电流作用.根据使用场合对 ...

  6. 棋牌APP下载链接在微信中被封拦截屏蔽无法打开的原因和解决办法

    接上一篇文章:https://blog.csdn.net/rolycn16/article/details/89014862 我们继续聊聊微信中浏览器下载链接打不开的情况 在我们做营销活动或推广宣传的 ...

  7. html中如何屏蔽一段代码,html中如何使用python屏蔽一些基本功能(示例代码)

    进行数据解析的理由不计其数,相关的工具和技巧也同样如此.但是,当您需要用这些数据做一些新的事情时,即使有"合适的"工具可能也是不够的.这一担心对于异类数据源的集成同样存在.用来做这 ...

  8. linux进程中对信号的屏蔽,linux进程中的信号屏蔽

    在linux的进程中可以接收到各种的信号,并且如果你不对信号进行处理,linux中的进程就会采用默认的处理方式处理,比如ctrl-c的信号,进程对它的处理就是终止进程的执行. 在linux中,我们也可 ...

  9. PyCairo 中的变换

    在 PyCairo 图形学编程教程的这个部分,我们将讨论变换. 一个 仿射变换 由 0 个或多个线性变换(旋转,放缩或切变)和平移(移位)组成.多个线性变换可以结合为以单个矩阵表示. 旋转 是将一个刚 ...

最新文章

  1. 刷了半年LeetCode,总共500题,拿到了 Google 的 special offer,记下笔记,感谢这些很有用的公众号...
  2. [蓝桥杯2017初赛]包子凑数-模拟+巧妙枚举
  3. 收入超10亿?罗永浩:要真有这个收入 我早就还完债做智能产品去了
  4. 易语言 钩子 (钩子HOOK与APIHOOK是不一样的)
  5. 1177: 按要求排序(指针专题)_排序算法之快速排序
  6. 学到一招!三行 Python 代码轻松提取 PDF 表格数据!
  7. bch纠错码 码长8_从HDMI视频数据带有BCH纠错码讨论线材对画质的影响
  8. layerdate一款很好用日期插件
  9. ios沙箱软件_ios沙盒2存档-ios沙盒2最新版下载0.5.2苹果版-西西软件下载
  10. 日知录(七):python之理解pygame飞机大战
  11. python代码情话_程序员的土味情话~(内含表白代码)
  12. kartoslam找bug之行
  13. 微信上线支付分对标芝麻信用分,教你如何开通!
  14. python代码加密运行_python源码下载后怎样进行加密
  15. WampServer最新版一键安装
  16. 【Web技术】919- 前端关于单点登录的知识
  17. cdr mac majave os_苹果最新 macOS Mojave 10.14 正式版 懒人镜像
  18. windows10忘记开机密码解决办法
  19. 计算机专业的单招大学排名,全国单招学校排名 单招哪个学校比较好
  20. 超级简单易懂的蓝桥杯《成绩统计》解法

热门文章

  1. 数据库分库分表的几种方式
  2. java中的equals拿什么鞋的_Java中==和equals方法
  3. Spring Cloud Gateway 源码解析(4)-- filter
  4. redis(15)--复制
  5. 实习笔记0708 https协议/ django中间件/接口测试/内网与外网/域名系统DNS
  6. 【图文详解】JDK1.8的安装与环境变量配置(win10)
  7. 一次性掌握JDK、JRE、JVM的概念以及三者之间的关系【2021整理】
  8. 华大单片机HC32L136J8TA读取DS18B20温度(源码+时钟配置)
  9. Linux读写执行(RWX)权限
  10. HMAC-SHA1加密