OpenGL 超级宝典学习笔记操作像素
Abstract Keywords OpenGL 技术笔记 OpenGL
Citation Yao Qing-sheng.OpenGL 超级宝典学习笔记操作像素.FUTURE & CIVILIZATION Natural/Social Philosophy & Infomation Sciences,20220628. https://yaoqs.github.io/20220628/opengl-chao-ji-bao-dian-xue-xi-bi-ji-cao-zuo-xiang-su/
OpenGL 支持放大,缩小,旋转图像。下面将举例介绍这些像素的操作。下面的例子是从 tga 文件中读取图片并显示,而且可以通过右键菜单来选择图像的显示模式和保存图片的快照到磁盘命名为 screenshot.tga。完整的代码示例如下:
1 |
|
SetupRC 函数用于加载图像数据,保存图像数据,图像的宽高和格式等信息。
1 | glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //设置像素的存储格式 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //加载图像数据 pImage = gltLoadTGA("horse.tga", &iWidth, &iHeight, &iComponents, &eFormat); |
在程序退出时,记得释放为图像数据分配的内存,在 ShutdownRC 中释放图像数据
1 | if (pImage) |
在 main 函数中,创建菜单,为每个菜单项分配键值,然后绑定到右键上。
1 | //设置菜单 int menuID = glutCreateMenu(ProcessMenu); |
根据所选择的菜单进行相应的操作,默认情况下是通过 glDrawPixels 函数把图像放置在窗口的左下角显示。第一个菜单项 Save Image 是保存图像的快照。
¶ 像素缩放
常见的图像操作,放大和缩小图像。OpenGL 提供了一个对图像进行缩放的函数:
1 | void glPixelZoom(GLfloat xfactor, GLfloat yfactor); |
xfactor,yfactor 指定了在 x,y 方向上缩放的倍数。图像的缩放包括了放大,缩小和反转。例如:如果 x 方向上的缩放因子为 2,那么图像在 x 方向上会放大 2 被。在本例中选择第三项菜单可以把图像填满窗口:
1 | //让图像填充满屏幕 GLint viewport[4]; //取得视口的大小 glGetIntegerv(GL_VIEWPORT, viewport); //按比例缩放 glPixelZoom((GLfloat)viewport[2]/iWidth, (GLfloat)viewport[3]/iHeight); |
如果缩放因子为负值,效果就是沿缩放方向进行反转。此时不仅仅反转了图像中像素的排列顺序,而且也翻转图像根据光栅位置在屏幕上绘制的方向。例如,一般是图像的左下角放置在当前光栅位置,如果两个缩放因子都为负值则图像的右上角被放置在当前光栅位置处:
1 | //图像倒转 glPixelZoom(-1.0f, -1.0f); //倒转后的图像的,渲染方向也倒转过来了,变成了从右上角���始往左下角渲染,所以设置倒转后的光栅位置为图像的宽高。 glRasterPos2i(iWidth, iHeight); |
¶ 像素变换
除了像素的缩放之外,OpenGL 还支持对图像进行一些简单的数学操作。把像素转移到颜色缓冲区或者从颜色缓冲区转移出来。可以调用下面两个函数来实现:
1 | void glPixelTransferi(GLenum pname, GLint param); |
pname 的枚举值如下表:
缩放和偏转参数允许缩放和偏转单独的颜色通道。缩放因子将与颜色成分值相乘,偏转值则与颜色成分值相加。公式如下:
新值 = (旧值 * 缩放因子)+ 偏转值
默认情况下缩放因子是 1.0,偏转值是 0.0。如果想让图像只显示红色成分值,则可以设置绿色和蓝色的缩放因子为 0.0.
1 | glPixelTransferf(GL_GREEN_SCALE, 0.0f); |
例子中,分别显示红色,绿色,蓝色成分值的代码:
1 | case 4: //只保留红色 glPixelTransferf(GL_RED_SCALE, 1.0f); |
在绘制完成后把各个颜色通道的缩放因子复原。
1 | //还原 glPixelTransferf(GL_RED_SCALE, 1.0f); |
我们还可以把一幅彩色图像转成黑白颜色来显示。首先把彩色图像渲染到颜色缓冲区中:
1 | glDrawPixels(iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pImage); |
然后分配一个用来保存每个像素亮度值的内存空间:
1 | pModifyImage = (GLbyte *)malloc(iWidth* iHeight); |
亮度图像只有一个通道,所以我们只分配一个字节来存储亮度值。把当前颜色缓冲区中的颜色通道进行变换:使用 NTSC(美国国家电视系统委员会)标准转成黑白图像
1 | glPixelTransferf(GL_RED_SCALE, 0.3f); |
然后通过 glReadPixel 来从颜色缓冲区中读取图像的亮度值到 pModifyImage 指向的内存区域中。
1 | glReadPixel(0, 0, iWidth, iHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pModifyImage); |
最后把 pModifyImage 的数据写会颜色缓冲区中:
1 | glDrawPixel(iWidth, iHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pModifyImage); |
OpenGl 把彩色图像转换成亮度图,只是把各个颜色通道的值相加得到亮度值,超过 1.0 的设置为 1.0,这样得到的效果不是很好:
为了得到更好的效果,我们可以通过 NTSC 标准把彩色图像转换成灰度图。从 RGB 颜色空间转换到黑白色彩空间的转换公式是:
亮度 = (0.3 红色) + (0.59 绿色) + (0.11 * 蓝色);
1 | //NTSC标准 glPixelTransferf(GL_RED_SCALE, 0.3f); |
得到的效果是更好看的灰度图:
OpenGL 超级宝典 第 4 版 中文版 PDF + 英文版 + 源代码 见 http://www.linuxidc.com/Linux/2013-10/91413.htm
OpenGL 编程指南(原书第 7 版)中文扫描版 PDF 下载 http://www.linuxidc.com/Linux/2012-08/67925.htm
OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm
Ubuntu 13.04 安装 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm
OpenGL 三维球体数据生成与绘制【附源码】 http://www.linuxidc.com/Linux/2013-04/83235.htm
Ubuntu 下 OpenGL 编程基础解析 http://www.linuxidc.com/Linux/2013-03/81675.htm
如何在 Ubuntu 使用 eclipse for c++ 配置 OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm
更多《OpenGL 超级宝典学习笔记》相关知识 见 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581
Address:Department of Natural/Social Philosophy & Infomation Sciences, CHINA
Biography...
转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!
Like this article? Support the author with