热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[翻译]PyCairo指南裁剪和masking

裁剪和masking在PyCairo指南的这个部分,我么将讨论裁剪和masking操作。裁剪裁剪就是将图形的绘制限定在一定的区域内。这样做有一些效率的因素࿰





裁剪和masking
在PyCairo指南的这个部分,我么将讨论裁剪和masking操作。

裁剪


裁剪就是将图形的绘制限定在一定的区域内。这样做有一些效率的因素,同时也可以创建一些非常有趣的效果。PyCairo有一个clip()方法来设置裁剪区域。



#!/usr/bin/python
'''
ZetCode PyCairo tutorial
This program shows how to perform
clipping in PyCairo
author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''
import cairo
import gtk
import math
import glib
import random
class MainWindow(gtk.Window):
def __init__(self):
super(self.__class__, self).__init__()
self.init_ui()
self.load_image()
self.init_vars()
def init_ui(self):
self.darea = gtk.DrawingArea()
self.darea.connect("expose_event", self.expose)
self.add(self.darea)

glib.timeout_add(100, self.on_timer)
self.set_title("Clipping")
self.resize(300, 200)
self.set_position(gtk.WIN_POS_CENTER)
self.connect("delete-event", gtk.main_quit)
self.show_all()
def expose(self, widget, event):
self.context = widget.window.cairo_create()
self.on_draw(300, self.context)

def on_draw(self, wdith, cr):
w, h = self.get_size()

if (self.pos_x <0 &#43; self.radius):
self.delta[0] &#61; random.randint(5, 9)
elif (self.pos_x > w - self.radius):
self.delta[0] &#61; - random.randint(5, 9)

if (self.pos_y <0 &#43; self.radius):
self.delta[1] &#61; random.randint(5, 9)
elif (self.pos_y > h - self.radius):
self.delta[1] &#61; - 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 load_image(self):
self.image &#61; cairo.ImageSurface.create_from_png("beckov.png")

def init_vars(self):
self.pos_x &#61; 128
self.pos_y &#61; 128
self.radius &#61; 40

self.delta &#61; [3, 3]

def on_timer(self):
self.pos_x &#43;&#61; self.delta[0]
self.pos_y &#43;&#61; self.delta[1]
self.darea.queue_draw()
return True;
def main():
window &#61; MainWindow()
gtk.main()

if __name__ &#61;&#61; "__main__":
main()

这个例子中&#xff0c;我们将裁剪一幅图片。一个圆形在窗口区域中移动&#xff0c;使得下面的图片只有一部分显示出来。这就好像我们从一个洞中看过去一样。


def load_image(self):
self.image &#61; cairo.ImageSurface.create_from_png("beckov.png")

这是下面的那副图片。每一个定时器周期&#xff0c;我们都将看到这幅图片的一部分。



if (self.pos_x <0 &#43; self.radius):
self.delta[0] &#61; random.randint(5, 9)
elif (self.pos_x > w - self.radius):
self.delta[0] &#61; - random.randint(5, 9)

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



cr.arc(self.pos_x, self.pos_y, self.radius, 0, 2 *math.pi)
这一行添加一个圆形的path到Cairo上下文。



cr.clip()
clip()设置一个裁剪区域。裁剪区域是当前正在使用的path。当前的path有arc()方法调用创建。


cr.paint()

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




Figure: Clipping




Masking


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



#!/usr/bin/python
&#39;&#39;&#39;
ZetCode PyCairo tutorial
This program demonstrates masking.
author: Jan Bodnar
website: zetcode.com
last edited: August 2012
&#39;&#39;&#39;
import cairo
import gtk
class MainWindow(gtk.Window):
def __init__(self):
super(self.__class__, self).__init__()
self.init_ui()
self.load_image()
def init_ui(self):
self.darea &#61; gtk.DrawingArea()
self.darea.connect("expose_event", self.expose)
self.add(self.darea)

self.set_title("Masking")
self.resize(310, 100)
self.set_position(gtk.WIN_POS_CENTER)
self.connect("delete-event", gtk.main_quit)
self.show_all()
def expose(self, widget, event):
self.context &#61; widget.window.cairo_create()
self.on_draw(300, self.context)

def on_draw(self, wdith, cr):
cr.mask_surface(self.ims, 0, 0)
cr.fill()
def load_image(self):
self.ims &#61; cairo.ImageSurface.create_from_png("omen.png")
def main():
window &#61; MainWindow()
gtk.main()

if __name__ &#61;&#61; "__main__":
main()

在这个例子中&#xff0c;哪些地方需要绘制和哪些地方不绘。



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

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




Figure: Masking




Blind down effect


在这个例子中&#xff0c;我们将blind down我们的图片。这类似于我们使用的遮光窗帘。



#!/usr/bin/python
&#39;&#39;&#39;
ZetCode PyCairo tutorial
This program creates a blind down
effect using masking operation
author: Jan Bodnar
website: zetcode.com
last edited: August 2012
&#39;&#39;&#39;
import gtk, glib
import cairo
import math
class MainWindow(gtk.Window):
def __init__(self):
super(self.__class__, self).__init__()
self.init_ui()
self.load_image()
self.init_vars()
def init_ui(self):
self.darea &#61; gtk.DrawingArea()
self.darea.connect("expose_event", self.expose)
self.add(self.darea)

glib.timeout_add(35, self.on_timer)

self.set_title("Blind down")
self.resize(325, 250)
self.set_position(gtk.WIN_POS_CENTER)
self.connect("delete-event", gtk.main_quit)
self.show_all()
def load_image(self):
self.image &#61; cairo.ImageSurface.create_from_png("beckov.png")
def init_vars(self):
self.timer &#61; True
self.h &#61; 0
self.iw &#61; self.image.get_width()
self.ih &#61; self.image.get_height()

self.ims &#61; cairo.ImageSurface(cairo.FORMAT_ARGB32, self.iw, self.ih)

def on_timer(self):
if (not self.timer):
return False

self.darea.queue_draw()
return True

def expose(self, widget, event):
self.context &#61; widget.window.cairo_create()
self.on_draw(300, self.context)

def on_draw(self, wdith, cr):
ic &#61; cairo.Context(self.ims)
ic.rectangle(0, 0, self.iw, self.h)
ic.fill()

self.h &#43;&#61; 1

if (self.h &#61;&#61; self.ih):
self.timer &#61; False

cr.set_source_surface(self.image, 10, 10)
cr.mask_surface(self.ims, 10, 10)
def main():
window &#61; MainWindow()
gtk.main()

if __name__ &#61;&#61; "__main__":
main()

blend down效果背后的想法相当的简单。图像是h个像素高的。我们画0&#xff0c;1&#xff0c; 2...个1像素高的
行。每一个周期&#xff0c;图像的部分多出一像素的高度&#xff0c;直到整幅图片都变得可见为止。



def load_image(self):
self.image &#61; cairo.ImageSurface.create_from_png("beckov.png")

load_image()方法中&#xff0c;我们有一幅PNG图片创建一个图片surface。



def init_vars(self):
self.timer &#61; True
self.h &#61; 0
self.iw &#61; self.image.get_width()
self.ih &#61; self.image.get_height()

self.ims &#61; cairo.ImageSurface(cairo.FORMAT_ARGB32, self.iw, self.ih)

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



ic &#61; cairo.Context(self.ims)

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



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

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



self.h &#43;&#61; 1
将要显示的图像的高度被加了一个单元。



if (self.h &#61;&#61; self.ih):
self.timer &#61; False

当我们在GTK窗口中绘制了整个的图像时&#xff0c;我们停掉了定时器方法。



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

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




Figure&#xff1a;Blind down


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







转载于:https://my.oschina.net/wolfcs/blog/132773



推荐阅读
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • python的交互模式怎么输出名文汉字[python常见问题]
    在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>,此时我们可以使用print() ... [详细]
  • 火星商店问题:线段树分治与持久化Trie树的应用
    本题涉及编号为1至n的火星商店,每个商店有一个永久商品价值v。操作包括每天在指定商店增加一个新商品,以及查询某段时间内某些商店中所有商品(含永久商品)与给定密码值的最大异或结果。通过线段树分治和持久化Trie树来高效解决此问题。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
author-avatar
手机用户2602911885
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有