Mastering openFrameworks_第四章_图片和纹理

图片和纹理

仅仅使用基本的几何元素来创建丰富的可视化效果通常是不够的。图像是帮助增加装饰,风格,甚至照片现实主义到一个互动场景的积木。在本章中,我们将介绍可以在图像上执行的基本操作:

加载和绘制图像

旋转图像

色彩调制

透明度

创建和修改图像

使用ofTexture进行内存优化

图像变形和视频映射

光栅和矢量图像

在计算机图形学和计算机视觉中,图像是一种用途广泛的二维图像。有两类图像:光栅图像和矢量图像。

光栅图像是由图像元素(称为像素)组成的矩形阵列,对于表示来自数码相机的照片来说,它们是很自然的。现代计算机屏幕是像素的物理阵列,因此屏幕是显示光栅图像的自然设备。

矢量图像由许多图形元素(如直线、圆形和曲线)组成,它们很自然地用于表示精确的绘图(如卡通和图形)。矢量图像可以放大,没有任何质量损失,并增加了存储器的大小,因此,他们用于参数化绘图。

可以处理光栅和矢量图像。在这一章中,我们将只处理光栅图像。为了处理矢量图像,

示例/插件/svgexample示例。

让我们考虑从文件中加载图像的两个基本操作

在屏幕上画出来。

加载和绘制图像

要加载和绘制图像,需要声明图像对象,从文件中加载图像,并在testApp::draw()函数中添加一个绘图函数调用。执行以下步骤:

1.将图像声明为ofImage对象:

ofImage image;

最好的方法是在testApp.h文件中的testApp类声明中声明图像。为了简单起见,有时我们将在testApp.cpp文件上面声明它们。

2.使用loadImage函数从文件中加载图像:

image.loadImage( fileName );

这里,fileName是一个指定文件名的字符串值;例如,sunflower.png。通常,图像应该位于应用程序的bin/data文件夹中。如果要使用其他文件夹中的图像,可以使用绝对路径;例如,在Windows中使用image.loadImage(“c:myimage.png”)。

3.使用testApp::Draw()函数中的image.Draw(x,y)函数绘制图像。在这里,x和y是指定屏幕上图像左上角的浮点值。

让我们在一个项目中实现这些步骤。它只是在屏幕上绘制一个图像。该项目基于openFrameworks的emptyExample示例。用示例复制文件夹并重命名它。然后将图像sunflower.png放入项目的bin/data文件夹中。现在,用下面的代码替换testApp.cpp文件的开头:

#include "testApp.h" 
ofImage image; //Declare image object 
void testApp::setup(){ 
//Load image file 
image.loadImage("sunflower.png"); 
} 
void testApp::update(){ 
} 
void testApp::draw(){ 
//Set up gray background 
ofBackground(128, 128, 128); 
//Draw image with top left corner x=100, y=50 pixels 
image.draw( 100, 50 ); 
}

运行该项目;您将看到下面在屏幕截图中显示的图像。

如您所见,我们使用了PNG格式的图像。此外,openFrameworks允许我们以JPG、BMP和TIFF文件格式加载和保存图像。其中,PNG是最有用的,因为它保持了原始图像的高质量,可以保持透明度,具有小文件尺寸,解码速度非常快。Jpg适合拍摄平滑逼真的图片,比如照片。这种格式可以减少可见图像的质量,并不与透明度工作,但有更小的文件大小的情况下,真实的照片。Bmp和TIFF以未压缩的形式存储图像。它们有利于保存和处理图像而不会丢失质量。它们很少用于交互式应用程序,因为它们的文件大小太大,而且从这些文件中加载图像的速度很慢。

您不仅可以加载图像,还可以将它们保存到PNG、JPG、BMP或TIFF文件中。为此,请使用image.saveImage()方法。参见下面的例子:

image.saveImage( "test.png" );

可以使用draw()方法的重载版本:image.draw(x,y,w,h)在屏幕上移动、缩放和拉伸图像。它绘制图像对象,另外指定像素的宽度w和高度h。

另外,还有image.draw()方法的重载版本,它允许我们简化代码:

1.image.draw( p ) -使用point类型的点p绘制图像。

2.image.draw( rect ) – 使用矩形rect类型绘制图像ofRectangle。

要检索以像素为单位的原始图像大小,可以使用其width和height字段image.width和image.height,其类型为int。以下是使用这些方法的例子:

3.绘制一个大小为其50%的图像,左上角为(0,0):

image.draw( 0, 0, image.width*0.5, image.height*0.5 );

4.绘制宽度等于300像素和高度成比例的图像:

image.draw( 0, 0, 300, 300.0*image.height/image.width );

5.绘制任意比例的图像;例如,宽度100,高度200:

image.draw( 0, 0, 100, 200 );

6.可以使用宽度或高度的负值翻转图像。例如,对于垂直翻转,使用以下代码:

image.draw( 0, image.height, image.width, -image.height);

注意:而不是在图像的参数中写入大的公式。Draw(x,y,w,h)方法,您可以使用ofTranslate(x,y)和ofScale(scaleX,scaleY)方法移动和缩放坐标系,该方法用于绘制屏幕上的所有内容。(参见第2章的坐标系变换部分,2D绘图以了解细节。)您可以在需要的连续性中调用ofTranslate()和ofScale()来获得所需的转换。如果您对坐标转换不是很熟悉,那么看起来就会很难。但是,相信我,它使您的代码更加干净、易于阅读和维护。另外,请参阅下一节了解详细信息。

旋转图像

image.draw()方法没有参数来旋转任意角度的图像。为了达到这个效果,我们需要使用坐标系/坐标系转换,这些转换将在坐标系/值转换中详细描述第二章二维绘图部分。

我们需要执行以下步骤来绘制旋转图像:

1.使用ofPushMatrix()存储当前变换矩阵。

2.使用ofRotate()应用旋转变换更改矩阵。

3.使用image.Draw()绘制图像。

4.使用ofPopMatrix()恢复原来的变换矩阵。

下面的代码演示了这些步骤。它绘制围绕当前坐标中心(0,0)旋转10度的图像。

void testApp::draw(){ 
ofPushMatrix(); //Store the transformation matrix 
ofRotate( 10.0 ); //Applying rotation on 10 degrees 
image.draw( 0, 0 ); //Draw image 
ofPopMatrix(); //Restore the transformation 
}

有时候,我们会想要旋转一个图像围绕其中心,而不是左上角。为了达到这个目的,我们需要将坐标中心平移到想要的旋转中心,旋转坐标系,最后绘制一个经过平移的图像,使图像的中心位于坐标中心。下面的代码通过绘制一个随时间慢慢旋转的图像来说明这一点:

void testApp::draw(){ 
ofPushMatrix (); 
//Shift center of coordinate system ( 0,0 ) to the desired 
//point, which will be rotation center 
ofTranslate( 500, 400 ); 
//Rotate coordinate system, 10 degrees per second 
ofRotate( 10.0 * ofGetElapsedTimef() ); 
//Draw image in a way that its center on the screen coincide 
//with ( 0,0 ) 
image.draw( -image.width/2, -image.height/2 ); 
ofPopMatrix(); 
}

此外,还有一种更优雅的方式来绘制以特定点为中心的图像。与使用image.draw(-image.width/2,-image.height/2)不同,我们可以更改图像的定位点,即在绘制图像时用作原点的点。可以通过调用以下函数来实现:

imag
### 回答1: 《Mastering Go》是一本关于Go语言的技术书籍,中文名为《Go语言编程》。这本书是由Mihalis Tsoukalos写的,旨在帮助读者提高自己在Go语言方面的技能和能力。 《Mastering Go》对Go语言的各个方面进行了全面深入的讲解,涵盖了从基础知识、语法和特性,到高级主题和实践技巧的内容。读者可以通过阅读本书,了解到Go语言的特点和优势,学习如何使用Go语言编写高效且可维护的程序。 这本书对Go语言的一些重要主题进行了详细的阐述,如并发和并行编程、网络编程、数据存储和数据库操作、测试和性能优化等。它还介绍了一些常见的Go语言开发工具和框架,帮助读者更加便捷地进行开发工作。 《Mastering Go》内容丰富且实用,作者通过给出大量的示例代码和案例,帮助读者更好地理解Go语言的使用方法和技巧。此外,本书还提供了一些练习和挑战,帮助读者巩固所学的知识,并提高自己的编程能力。 总之,《Mastering Go》是一本很值得阅读的Go语言技术书籍,对于想要深入学习和应用Go语言的开发者来说,它是一本宝贵的参考资料。无论是初学者还是有一定经验的开发者,读者都可以从中获得很多有用的知识和技能,从而提升自己在Go语言领域的水平。 ### 回答2: 《mastering_go_zh_cn-master》是一本关于Go编程语言的中文教程。Go是一种由Google开发的开源编程语言,它具有高效的并发性和轻量级的设计特点,用于构建快速、可靠和高性能的软件。这本教程旨在帮助读者从入门到精通掌握Go语言的使用。 这本教程覆盖了广泛的主题,包括基本语法、数据类型、控制流、函数、错误处理和并发编程等。它提供了大量的示例代码和练习题,帮助读者加深对Go语言的理解和应用。 《mastering_go_zh_cn-master》还对一些高级主题进行了深入讲解,如Go的垃圾回收机制、性能优化、包管理、程序测试和错误调试等。这些内容使读者能够更好地理解和使用Go语言,提高代码质量和开发效率。 该教程的作者对Go语言有深入的理解和实践经验,他提供了很多开发技巧和最佳实践,帮助读者避免一些常见的错误和陷阱。 总之,《mastering_go_zh_cn-master》是一本很好的Go语言教程,适合已有编程经验的读者学习和掌握Go的各个方面。无论是想要使用Go开发高效并发程序的工程师,还是想要扩展自己编程技能的爱好者,都可以从这本教程中获得很多价值。 ### 回答3: 《Mastering Go》是一本介绍Go编程语言的书籍,其中的"master"意味着掌握或精通。这本书由中文作者翻译自英文原版,名为《Mastering Go》。该书通过深入浅出的方式,向读者介绍了Go语言的各种核心概念、语法和高级特性,使读者能够在Go编程中达到熟练掌握的程度。 《Mastering Go》的中文翻译版本"master"是指完全掌握书中所涵盖的Go语言知识和技能。这本书精心组织了Go语言的各个方面的主题,包括并发编程、网络编程、内存管理、性能调优等。读者将会在每章中掌握使用Go编程语言进行实际开发的关键概念和技术。 这本书的目标受众是那些希望进一步提高他们Go编程技能的开发人员和学习者。对于具有一定程序设计基础的人来说,这本书是一个理想的学习资源,将帮助他们更好地理解Go语言,并将其应用于真实世界的项目中。 总之,《Mastering Go》是一本内容丰富且有深度的Go编程指南,通过阅读和学习这本书,人们可以有效地掌握Go语言的核心概念和高级特性,从而成为一个熟练的Go开发者。无论是对于初学者还是有经验的开发人员来说,这本书都是一个很好的学习资源,可以帮助他们更好地利用Go编程语言。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白茶等风12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值