渲染内存Rendering Buffer 我们先从这里开始:在内存中开辟一块存储区,然后将它的内容以最简单的光栅格式写到文件中,也就是 PPM(Portable Pixel Map)格式。虽然 Windows 对这种格式并没有原生的支持,但很多图像浏览器和转换器都能使用这种格式,比如 IrfanView(www.irfanview.com)。所有 AGG 的控制台例子都使用了 P6 256 格式,也就是 RGB,每个字节代码一个颜色。现在假设我们将在下图所示的 RGB-buffer 内存区中工作: 1.1 ### AGG中文手册知识点解析 #### 一、渲染内存(Rendering Buffer) 在计算机图形学领域,**渲染内存**(Rendering Buffer)是指用于保存图像数据的一块连续内存区域。这块内存通常用于存储像素值,以便进行图像处理或最终输出为可见的画面。 在本手册中提到的“在内存中开辟一块存储区”,指的是程序设计者需要预先分配一块足够大的内存空间来存储图像数据。这里的图像数据以最简单的光栅格式存储,即**PPM**(Portable Pixel Map)格式。 ##### 1.1 PPM 格式简介 - **PPM**是一种用于存储位图图像的标准格式之一,特别适合于原始像素数据的交换。 - 它有多种变体,包括P3和P6,其中P6用于表示真彩色图像(每个像素由三个字节组成,分别代表红、绿、蓝三种颜色分量),而P3用于表示灰度图像。 - 在AGG的例子中,使用的是P6 256格式,即RGB格式,每个颜色通道占用一个字节。 - 这种格式虽然不是Windows系统原生支持的格式,但是可以通过第三方工具如IrfanView等进行查看和转换。 #### 二、编写PPM文件 在给定的部分内容中,我们可以看到一个具体的示例代码,展示了如何将渲染内存中的数据写入到PPM文件中: ```cpp bool write_ppm(const unsigned char* buf, unsigned width, unsigned height, const char* file_name) { FILE* fd = fopen(file_name, "wb"); if (fd) { fprintf(fd, "P6\n%d %d\n255\n", width, height); fwrite(buf, 1, width * height * 3, fd); fclose(fd); return true; } return false; } ``` - 上述函数`write_ppm`接收四个参数:指向缓冲区的指针`buf`、宽度`width`、高度`height`以及文件名`file_name`。 - 函数内部首先打开指定文件,并向文件中写入PPM格式的头信息,包括格式类型(P6)、图像宽度、高度以及最大颜色值(255)。 - 然后,通过`fwrite`函数将整个缓冲区的数据写入文件。 - 最后关闭文件并返回操作是否成功的结果。 #### 三、绘制黑边框 在实际应用中,为了使图像看起来更加完整或者美观,常常会在图像的边缘添加一些装饰性的元素。例如,在给定的内容中,提供了一个`draw_black_frame`函数来绘制一个黑色的边框: ```cpp void draw_black_frame(agg::rendering_buffer& rbuf) { unsigned i; for (i = 0; i < rbuf.height(); ++i) { unsigned char* p = rbuf.row_ptr(i); *p++ = 0; *p++ = 0; *p++ = 0; p += (rbuf.width() - 2) * 3; *p++ = 0; *p++ = 0; *p++ = 0; } memset(rbuf.row_ptr(0), 0, rbuf.width() * 3); memset(rbuf.row_ptr(rbuf.height() - 1), 0, rbuf.width() * 3); } ``` - 这个函数遍历每一行(row),将每行的第一个和最后一个像素设置为黑色(0, 0, 0)。 - 通过使用`row_ptr`方法获取每一行的起始地址,并进行相应的赋值。 - 使用`memset`函数将第一行和最后一行完全填充为黑色。 #### 四、主函数实现 我们来看一下主函数`main`的具体实现: ```cpp int main() { // In the first example we do the following: // -------------------- // Allocate the buffer. // Clear the buffer, for now "manually" // Create the rendering buffer object // Do something simple, draw a diagonal line // Write the buffer to agg_test.ppm // Free memory unsigned char* buffer = new unsigned char[frame_width * frame_height * 3]; memset(buffer, 255, frame_width * frame_height * 3); agg::rendering_buffer rbuf(buffer, frame_width, frame_height, frame_width * 3); unsigned i; for (i = 0; i < rbuf.height() / 2; ++i) { unsigned char* ptr = rbuf.row_ptr(i) + i * 3; *ptr++ = 127; // R *ptr++ = 200; // G *ptr++ = 98; // B } draw_black_frame(rbuf); write_ppm(buffer, frame_width, frame_height, "agg_test.ppm"); delete[] buffer; return 0; } ``` - 主函数中首先分配了一块大小为`frame_width * frame_height * 3`的内存空间,并将其全部填充为白色。 - 创建`rendering_buffer`对象,并传入缓冲区指针、宽度、高度以及行步长。 - 使用循环绘制一条对角线。 - 调用`draw_black_frame`函数绘制黑边框。 - 调用`write_ppm`函数将缓冲区中的数据写入到PPM文件中,并释放内存。 本节介绍了如何使用AGG库创建和管理渲染内存、如何将内存中的图像数据写入PPM文件、如何在图像周围绘制黑边框,以及一个完整的示例代码。这些内容对于初学者理解和使用AGG库进行图像处理是非常有帮助的。
![application/x-gzip](https://img-home.csdnimg.cn/images/20210720083646.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![thumb](https://img-home.csdnimg.cn/images/20210720083646.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/release/download_crawler_static/4566417/bg1.jpg)
![](https://csdnimg.cn/release/download_crawler_static/4566417/bg2.jpg)
![](https://csdnimg.cn/release/download_crawler_static/4566417/bg3.jpg)
![](https://csdnimg.cn/release/download_crawler_static/4566417/bg4.jpg)
![](https://csdnimg.cn/release/download_crawler_static/4566417/bg5.jpg)
剩余77页未读,继续阅读
![avatar-default](https://csdnimg.cn/release/downloadcmsfe/public/img/lazyLogo2.1882d7f4.png)
- sharpglasses2013-03-10很好的资源。学习AGG图形引擎的好资料。
- myheyj2014-01-09挺好的,适合初学者。
- jk2769938572013-04-28学习了 还是有可学之处的
![avatar](https://profile-avatar.csdnimg.cn/b2774cc6d1da40898294e832c80c27b6_ndsccwf.jpg!1)
- 粉丝: 7
- 资源: 1
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![voice](https://csdnimg.cn/release/downloadcmsfe/public/img/voice.245cc511.png)
![center-task](https://csdnimg.cn/release/downloadcmsfe/public/img/center-task.c2eda91a.png)
最新资源
- SSA-Catboost麻雀搜索算法优化Catboost分类预测,优化前后对比(Matlab完整源码和数据)
- 事件触发控制代码,每个代码有对应参考文献 1.多智能体中基于事件触发的协议 2.多智能体分布式系统的事件触发控制 3.基于观测器
- Python实现 ChatOps 的最简单最受欢迎的聊天机器人
- Python GraphQL 框架
- Emacs Python 开发环境
- 如何在Windows 11未检测到耳机时修复它
- HBA-Catboost蜜獾优化算法优化Catboost分类预测,优化前后对比(Matlab完整源码和数据)
- 1517-基于51单片机的双机通信(数码管,数字,LED)proteus、原理图、流程图、物料清单、仿真图、源代码.zip
- 1516-基于51单片机的双机通信(键值,LCD)proteus,原理图、流程图、物料清单、仿真图、源代码.zip
- 鲸鱼算法算支持向量机SVM回归分析,鲸鱼算法优化支持向量机SVM沉降预测(代码完整,数据齐全)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)
![dialog-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/green-success.6a4acb44.png)