博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《交互式程序设计 第2版》一3.7 将外部数据载入Processing
阅读量:5748 次
发布时间:2019-06-18

本文共 5483 字,大约阅读时间需要 18 分钟。

本节书摘来华章计算机《交互式程序设计 第2版》一书中的第3章 ,第3.7节,Joshua Noble 著 毛顺兵 张婷婷 陈宇 沈鑫 任灿江 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.7 将外部数据载入Processing

目前已经介绍了一些Processing绘图基础和基本的用户交互捕获方式,你还要学习如何在Processing中载入数据、图像和视频。前面已经提及Processing项目的默认设置,知道了可以在和.pde同名的文件夹下建立data文件夹来存放所需的数据。Processing应用程序希望把所有需要的数据都放入data文件夹中。如果你想载入一个名叫sample.jpg的文件,你应该把该文件放到与正在处理的.pde文件同名的文件夹下的data文件夹中。

3.7.1 载入并显示图像

首先,你要学会如何载入图像。载入和显示图像的最基本的手段是一个类和两个方法:PImage类、loadImage()方法和image()方法。

PImage类
Processing依靠一个名为PImage的类来对图像进行显示和缩放。当你创建了一个PImage对象后,你就可以将图像装入到这个对象中,然后可将图像显示出来。想声明一个PImage对象,可以在程序的任何地方声明,但最好在程序代码的顶端,如下所示:

PImage img;

在声明了PImage对象之后,可以用loadImage()方法将图像装入到该对象中。

loadImage()方法
该方法将图像文件名作为参数,将此图像装入到PImage对象中。图像文件名既可以是文件系统中的(具体到Processing软件,是你的项目目录的data目录中的文件名),也可以是用URL表示的文件名。这意味着你可以装入一个来自Internet的图像文件,象下面这样:

PImage rocks;rocks = loadImage("http://thefactoryfactory.com/images/hello.jpg");

你也可以装入你的项目目录的data文件夹中的图像,像下面这样:

PImage rocks;rocks = loadImage("hello.jpg");

loadImage()方法可以装入JPEG、PNG、GIF和TGA格式的图像。其他格式的图像,如TIF、BMP或RAW,是无法用Processing显示的,除非对Processing的一些方法进行认真修改。

你已经学习了如何声明图像对象和如何装入图像,剩下的就是如何用image()方法来显示图像。
image()方法
image()方法有3个参数:

image(PImage, xPosition, yPosition);

第一个参数是要被显示的PImage图像对象。如果只是声明了该对象,还未用loadImage()方法创建它,那么用image()方法去显示它会引发一个错误。有一些技巧可以解决这个问题,我们留到第10章来讲。在目前可以这样讲,一个PImage对象只有在装入图像之后,才能用image()方法来显示。另两个参数是图像放到窗口上以后左上角的x和y坐标,它们表明了图像在窗口上的摆放位置。参考示例3-13。

示例3-13:image.pde

PImage img;void setup() {    size(400, 400);    img = loadImage("sample.jpg");    image(img, 0, 0);}

只要setup()方法被调用,那么窗口大小就确定了,图像文件sample.jpg就被装入PImage对象并被显示在窗口的(0,0)处(即窗口的左上角)。也可以用image()方法对PImage图像对象中的图形进行缩放。就象Processing中的很多方法一样,image()也是一组重载方法,你可以在调用时将想要的图像宽度和高度作为参数传递给它:

image(img, x, y, width, height)

如果没有指明宽度和高度,图像会以实际尺寸显示在窗口上。如果图像太大,就只能显示一部分。你也可以指定显示时的宽度和高度,以便对图像进行缩放。如果指定的宽高比和图像实际的宽高比不一致,那么图像会出现拉伸或挤压现象。

3.7.2 显示视频

Processing程序包含了一个名为Movie的类来显示视频。该类依赖苹果公司的QuickTime视频处理库,因此如果你的计算机还没有安装这个库,你需要下载并安装它。要说明的是,目前在Linux上用Processing处理视频是相当困难和复杂的。GSVideo库很新,设置过程稍显复杂;但它看起来相当可行,它允许Linux用户在Processing中处理不同格式的视频。为了本书的简洁性考虑,我们将它留给读者去自行研究。

3.7.3 使用Movie类

用Movie类可以装入QuickTime视频;可以装入扩展名为.mov的视频文件;可以播放、循环、暂停;可以改变播放速度;可以调整视频色彩。用Movie类创建视频对象和用PImage类创建图像对象有些相似,但也有一个很大的不同:你需要先导入包含Movie类相关信息以及视频处理的所有库。这些库放置在另一个地方,可以用导入语句import来访问,如下所示:

import processing.video.*;

接下来声明一个Movie变量:

Movie mov;

在setup()方法中,你需要创建一个Movie类的实例。如何创建呢?你可以调用Movie类的构造函数。该类的构造函数也是一组重载方法,有4种签名:

Movie(parent, filename)Movie(parent, filename, fps)Movie(parent, url)Movie(parent, url, fps)

参数parent是将要使用和显示视频的Processing应用程序。在简单的应用程序中,参数parent往往是这个应用程序本身,所以你可以用关键字this来引用它:

Movie(this, "http://sample.com/movie.mov");

这不是非理解不可的。每一个Processing应用程序都是名为PApplet的Java类的实例。PApplet类调用setup()方法和draw()方法,处理鼠标和键盘事件。有时,一个应用程序实例被载入另一个应用程序中,内部的那个称为PApplet子对象,外部的称为PApplet父对象。如果在子对象中引用父对象,那么父对象就是居于外部的那个应用程序。这点比较高深难懂,你多半也不想面对它。如果你遇到parent参数使用this关键字或PApplet对象作实参,你会知道这些实参都引用主程序类。

用filename和url参数表示视频文件都是可行的,这就象用loadImage()方法装载本地图像和网络上的图像一样。当要载入本机上的一个.mov文件时,用该文件的文件名。当要载入网络上的一个视频时,就用URL方式。最后有可选的参数fps表示帧速率。如果视频自身的帧速率和应用程序的帧速率不同,你可以用这个参数设置读取视频时的帧速率。下面的代码在Processing应用程序的setup()方法中,使用对该程序的引用和本地视频文件作为参数,从而构造了一个Movie对象:

void setup() {    size(320, 240);    mov = new Movie(this, "sample.mov");    mov.play();}

看看代码中的play()方法。它告诉Processing应用程序要立刻读取视频文件。这很重要,因为如果不调用这个方法,那么Processing应用程序就不会从视频中读取视频帧,也就不会显示视频。想要让Processing应用程序显示视频,你必须调用play()方法或loop()方法。

要读视频,你需要定义一个movieEvent()方法。为什么呢?当QuickTime播放视频时,视频片段或帧(和视频帧没有太大区别)源源不断地流向Processing应用程序,而Processing应用程序会将它们显示在窗口上。QuickTime播放器准备好一个视频帧后,通过调用movieEvent()方法来告诉Processing环境,一个视频帧准备显示了。这和mousePressed()的原理是一样的,mousePressed()告诉Processing环境发生了鼠标按键事件。想要获得该帧的信息,你需要调用Movie类的read()方法。该方法读取一帧的信息并放到Movie对象中,准备显示出来:

void movieEvent(Movie m) {    m.read();}

要在窗口中显示当前视频帧,你可以用image()方法。这与前面所讲的用image()方法来显示PImage对象中的图像一样。

void draw() {    image(mov, 0, 0);}

这段代码将当前视频帧显示在(0,0)处(即窗口左上角)。图3-7是示例3-14的应用程序运行时的画面。

示例3-14:movie.pde

import processing.video.*;Movie mov;    void setup() {    size(320, 240);    mov = new Movie(this, "sample.mov");    mov.play();}void movieEvent(Movie m) {    m.read();}void draw() {    image(mov, 0, 0);}

image

图3-7:用Movie类显示视频

3.7.4 读写文件

最后还要了解如何读写文件。要读一个文件有两种方式,其中一种就是根据文件类型使用对应的载入方法。要载入图像,可以用loadImage()方法;要载入简单文本文件,可以用loadStrings()方法;要载入二进制文件(除文本文件之外的其他文件),可以用loadBytes()方法。由于载入和分析二进制文件要复杂得多,我们将这些内容留到第12章来讲,本节只讲简单文本文件的读写。

loadStrings()方法
仅当要载入纯文本文件时,loadStrings()很有用。这就意味着,要用它来载入像Word文档这样的文件不会如你期望的那样顺利,因为Word文档中除了少量文本以外还包含了大量二进制数据。一般来讲,以.txt为扩展名的文件和没有扩展名的纯文本文件都是纯文本文件。也就是说,用Notepad和TextEdit创建的文件一定可以用loadStrings()方法正确载入。要用loadStrings()方法载入文件,括号中的参数既可以是本地电脑中的文件名,也可以是用URL方式表示的网络文件:

loadStrings("list.txt");

仅仅将文本文件载入还不够,还需要将文件内的数据存放在某个地方。比如,将数据存放在一个字符串对象数组中:

String lines[] = loadStrings("list.txt");

这条语句建立了一个字符串数组来存放文本文件的所有行,数组中的每个元素可以引用文件中的一行。要显示这些字符串,需要用一个for循环。每一次循环,都会用text()方法将一个字符串显示在窗口画布上。参见示例3-15。

示例3-15:loadStringsDemo.pde

void setup(){    size(500, 400);    PFont font;    font = loadFont("Ziggurat-HTF-Black-32.vlw");    textFont(font, 32);    String[] lines = loadStrings("list.txt");    print("there are " + lines.length + " lines in your file");    for (int i=0; i < lines.length; i++) {    text(lines[i], 20 + i*30, 50 + i*30);//put each line in a new place    }}

再次提醒一下,所用到的文本文件必须位于Processing应用程序目录下的data文件夹中,或者来自Internet。

saveStrings()方法

前面介绍了用loadStrings()方法从文本文件中读取所有字符串,现在再学习如何将若干字符串输出到文本文件就很容易了。这两种操作是相反的。首先,需要建立字符串数组:

String[] lines = new String[4];lines[0] = "hello";lines[1] = "out";lines[2] = "there";lines[3] = "!";

建立字符串数组之后,调用saveStrings()方法就可以将数组中的所有字符串写到文本文件中。当然,调用时需要将文件名和数组名作为参数传递进去:

saveStrings("data/greeting.txt", lines);

这条语句建立了一个名为greeting.txt的文本文件,并将数组中所有字符串都写到该文件中,每个字符串在文件中占据一行。

转载地址:http://tzrzx.baihongyu.com/

你可能感兴趣的文章
Centos7同时运行多个Tomcat
查看>>
使用CocoaPods过程中的几个问题
查看>>
我的友情链接
查看>>
mysql数据类型---数值型---int
查看>>
为eclipse安装maven插件
查看>>
Android自动化压力测试——Monkey工具
查看>>
公司新年第一次全员大会小记
查看>>
最懒的程序员
查看>>
了解Amdahl定理,该定理再多核时代有怎样的影响?
查看>>
JAVA8 Stream 浅析
查看>>
inner join on, left join on, right join on要详细点的介绍
查看>>
SAS vs SSD对比测试MySQL tpch性能
查看>>
Spring boot 整合CXF webservice 全部被拦截的问题
查看>>
Pinpoint跨节点统计失败
查看>>
时间戳转换为时间(不为1970)
查看>>
win2003 NAT 访问互联网
查看>>
【Canal源码分析】Canal Server的启动和停止过程
查看>>
机房带宽暴涨问题分析及解决方法
查看>>
wdOS系统下源码编译安装LAMP环境(linux+apache+php+mysql)
查看>>
iOS 绕过相册权限漏洞
查看>>