#include<stdarg.h>
#include<png.h>
#include<glut.h>
#include<math.h>
#include<iostream> #pragma comment(lib,"libpng16.lib")//读取png图片
GLuint CreateTextureFromPng(const char* filename)
{
unsigned char header[8]; //8
int k; //用于循环
GLuint textureID; //贴图名字
int width, height; //记录图片到宽和高
png_byte color_type; //图片到类型(可能会用在是否是开启来通道)
png_byte bit_depth; //字节深度 png_structp png_ptr; //图片
png_infop info_ptr; //图片的信息
int number_of_passes; //隔行扫描
png_bytep * row_pointers;//图片的数据内容
int row,col,pos; //用于改变png像素排列的问题。
GLubyte *rgba; FILE *fp=fopen(filename,"rb");//以只读形式打开文件名为file_name的文件
if(!fp)//做出相应可能的错误处理
{
fclose(fp);//关闭打开的文件!给出默认贴图
return 0;//此处应该调用一个生成默认贴图返回ID的函数
}
//读取文件头判断是否所png图片.不是则做出相应处理
fread(header, 1, 8, fp);
if(png_sig_cmp(header,0,8))
{
fclose(fp);
return 0; //每个错误处理都是一样的!这样报错之后锁定就要花点小时间来!
} //根据libpng的libpng-manual.txt的说明使用文档 接下来必须初始化png_structp 和 png_infop
png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); //后三个是绑定错误以及警告的函数这里设置为空
if(!png_ptr)//做出相应到初始化失败的处理
{
fclose(fp);
return 0;
}
//根据初始化的png_ptr初始化png_infop
info_ptr=png_create_info_struct(png_ptr); if(!info_ptr)
{
//初始化失败以后销毁png_structp
png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
fclose(fp);
return 0;
} //老老实实按照libpng给到的说明稳定步骤来 错误处理!
if (setjmp(png_jmpbuf(png_ptr))) {
//释放占用的内存!然后关闭文件返回一个贴图ID此处应该调用一个生成默认贴图返回ID的函数 png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL); fclose(fp); return 0; }
//你需要确保是通过2进制打开的文件。通过i/o定制函数png_init_io
png_init_io(png_ptr,fp);
//似乎是说要告诉libpng文件从第几个开始missing
png_set_sig_bytes(png_ptr, 8);
//如果你只想简单的操作你现在可以实际读取图片信息了!
png_read_info(png_ptr, info_ptr);
//获得图片到信息 width height 颜色类型 字节深度
width = png_get_image_width(png_ptr, info_ptr);
height = png_get_image_height(png_ptr, info_ptr);
color_type = png_get_color_type(png_ptr, info_ptr);
//如果图片带有alpha通道就需要
// if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) // png_set_swap_alpha(png_ptr);
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
//隔行扫描图片 这个必须要调用才能进行
number_of_passes = png_set_interlace_handling(png_ptr);
//将读取到的信息更新到info_ptr
png_read_update_info(png_ptr, info_ptr); //读文件
if (setjmp(png_jmpbuf(png_ptr))){
fclose(fp);
return 0;
}
rgba=(GLubyte*)malloc(width * height * 4);
//使用动态数组 设置长度
row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (k = 0; k < height; k++)
row_pointers[k] = NULL; //通过扫描流里面的每一行将得到的数据赋值给动态数组
for (k=0; k<height; k++)
//row_pointers[k] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
row_pointers[k] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr,
info_ptr));
//由于png他的像素是由 左-右-从顶到底 而贴图需要的像素都是从左-右-底到顶的所以在这里需要把像素内容进行一个从新排列
//读图片
png_read_image(png_ptr, row_pointers); pos = (width * height * 4) - (4 * width);
for( row = 0; row < height; row++)
{
for( col = 0; col < (4 * width); col += 4)
{
rgba[pos++] = row_pointers[row][col]; // red
rgba[pos++] = row_pointers[row][col + 1]; // green
rgba[pos++] = row_pointers[row][col + 2]; // blue
rgba[pos++] = row_pointers[row][col + 3]; // alpha
}
pos=(pos - (width * 4)*2);
} //开启纹理贴图特效
glEnable(GL_TEXTURE_2D); //创建纹理
glGenTextures(1,&textureID);
//绑定纹理
glBindTexture(GL_TEXTURE_2D,textureID); //将纹理绑定到名字 //设置贴图和纹理的混合效果这里是默认只用纹理
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//设置纹理所用到图片数据
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,rgba); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); free(row_pointers);
fclose(fp);
return textureID;
} void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,CreateTextureFromPng("test.png"));
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);glVertex2f(-60.0f,-60.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(60.0f, -60.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 60.0f, 60.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f( -60.0f, 60.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
} void Reshape(GLsizei w,GLsizei h)
{
if(h<0)
{
h=1;
}
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100,100,-100,100,-100,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} int main(int ac,char** av)
{
glutInit(&ac,av);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("pngtest");
glClearColor(1.0,1.0,1.0,1.0);
glutDisplayFunc(display);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}

OpenGL使用libPng读取png图片的更多相关文章

  1. 【转】 OpenGL使用libPng读取png图片

    觉得自己越来越无耻了呢?原文:http://laoyin.blog.51cto.com/4885213/895554 我复制到windows下也可以正常跑出来. #include<stdarg. ...

  2. [转]opengl入门例题(读取bmp图片,并显示)

    #include<gl/glut.h> #define FileName "bliss.bmp" static GLint imagewidth; static GLi ...

  3. libpng处理png图片(二)

    一,实现效果:图片剪切, 图片拼接                      ------------------切割后------------------>                  ...

  4. window.open()读取本地图片简单使用总结

    最近做了一个项目,需要读取本地图片出来,问了一些人,感觉在数据库中存取路径比较合适,故做此方法. 后台查询出来的路径

  5. 【原创】Android 4.4前后版本读取图库图片方式的变化

    Android 4.4前后版本读取图库图片方式的变化   本文讲述Android 4.4(KitKat)前后访问图库以及访问后通过图片路径读取图片的变化   Android 4.4(KitKat)以前 ...

  6. matlab读取多幅图片,并对读取的图片降采样和双三次插值

    clear all clc im = {}; %%创建字典im以保存读取的图片 dis = dir('C:\Users\KCl\Documents\MATLAB\SRCNN\Set5\*.bmp'); ...

  7. C#从SQL server数据库中读取l图片和存入图片

    原文:C#从SQL server数据库中读取l图片和存入图片 本实例主要介绍如何将图片存入数据库.将图片存入数据库,首先要在数据库中建立一张表,将存储图片的字段类型设为Image类型,用FileStr ...

  8. js读取本地图片并显示

    抄自 http://blog.csdn.net/qiulei_21/article/details/52785191 js读取本地图片并显示 第一种方法比较好 版权声明:本文为博主原创文章,未经博主允 ...

  9. java读取网页图片路径并下载到本地

    java读取网页图片路径并下载到本地 最近公司需要爬取一些网页上的数据,自己就简单的写了一个demo,其中有一些数据是图片,需要下载下来到本地并且 将图片的路径保存到数据库,示例代码如下: packa ...

随机推荐

  1. 使用GIT进行源码管理——GUI客户端

    很多人对GIT GUI客户端是非常不屑一顾的,但我非常喜欢GUI的方便快捷,也不用记忆冗杂的命令,本文简单的介绍了几种免费的Windows下的GIT客户端,方便大家使用. Git for Window ...

  2. 【基础知识】JavaScript基础

    [学习日记]JavaScript基础 1,一般写在<head></head>中(其实可以放到任意位置); 2,弹出对话框 <scripttype="text/j ...

  3. HTML基础-DAY1

    HTML基础 Web的本质就是利用浏览器访问socket服务端,socket服务端收到请求回复数据提供给浏览器进行渲染显示. import socket def main(): sock = sock ...

  4. thinkphp的_STORAGE_WRITE_ERROR_问题

    今天服务器突然报这个问题(上图所示),在thinkphp的官网上也发现有朋友碰到这个问题,定位到应该是Runtime目录没有写权限,然后试着给Application下的Runtime目录 chmod ...

  5. bzoj3456 城市规划 多项式求In

    \(n\)个点的无向联通图的个数 打着好累啊 一定要封装一个板子 记\(C(x)\)为无向图个数的指数型生成函数,\(C(0) = 1\) 记\(G(x)\)为无向联通图个数的指数型生成函数,\(G( ...

  6. Java输入输出入门 A+B

    描述 求两个整数之和. 输入 输入数据只包括两个整数A和B. 输出 两个整数的和. 样例输入 1 2 样例输出 3 import java.util.Scanner; public class Mai ...

  7. python开发_thread_线程_搜索本地文件

    在之前的blog中,曾经写到过关于搜索本地文件的技术文章 如: java开发_快速搜索本地文件_小应用程序 python开发_搜索本地文件信息写入文件 下面说说python中关于线程来搜索本地文件 利 ...

  8. "Blessing of Dimisionality: High Dimensional Feature and Its Efficient Compression for Face Verification"学习笔记

    这\(^{[1]}\)是一篇关于如何使用高维度特征在人脸验证中的文章,作者以主要LBP为例子,论述了高维特征和验证性能存在着正相关的关系,即人脸维度越高,验证的准确度就越高.由于那时候没有用DeepL ...

  9. 推荐一个简洁优雅的博客系统,farbox

    这是我用farbox搞的一个博客:http://www.jsnull.com/ 特点: 1.无数据库,数据存在dropbox里,需要自己注册一个dropbox帐号 2.静态文本文件即是文章,可以在任何 ...

  10. SpringMVC怎么获取前台传来的数组

    var tollerlist = new Array(); for(var k in objToller){ tollerlist.push(k); } $.ajax({ type:"pos ...