OpenGL显示图片
最近想用C++在windows下实现一个基本的图像查看器功能,目前只想到了使用GDI或OpenGL两种方式。由于实在不想用GDI的API了,就用OpenGL的方式实现了一下基本的显示功能。
用GDAL读取图像,这样就能与图像格式无关。OpenGL的glDrawPixels()函数也能实现图像显示,但是现在高版本的OpenGL都采用glTexImage2D()贴纹理的方式了,也不用考虑图像大小是否是2的N次方,或者4字节对齐的问题。具体实现如下:
// ImageShow.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "ImageShow.h"
#include <iostream>
#include <gl\glew.h> // 包含最新的gl.h,glu.h库
#include <gl\freeglut.h> // 包含OpenGL实用库
#include <gdal_priv.h>
using namespace std;
unsigned int texture; // 纹理对象
unsigned char* imgBuf = nullptr;
int imgWidth;
int imgHeight;
void ReadImage()
{
GDALAllRegister();
GDALDataset* img = (GDALDataset *)GDALOpen("lena.bmp", GA_ReadOnly);
//GDALDataset* img = (GDALDataset *)GDALOpen("dst.tif", GA_ReadOnly);
if (img == nullptr)
{
return;
}
imgWidth = img->GetRasterXSize(); //图像宽度
imgHeight = img->GetRasterYSize(); //图像高度
int bandNum = img->GetRasterCount(); //波段数
int depth = GDALGetDataTypeSize(img->GetRasterBand(1)->GetRasterDataType()) / 8; //图像深度
//申请buf
size_t imgBufNum = (size_t)imgWidth * imgHeight * bandNum * depth;
size_t imgBufOffset = (size_t)imgWidth * (imgHeight - 1) * bandNum * depth;
imgBuf = new GByte[imgBufNum];
//读取
img->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, imgBuf + imgBufOffset, imgWidth, imgHeight,
GDT_Byte, bandNum, nullptr, bandNum*depth, -imgWidth*bandNum*depth, depth);
GDALClose(img);
}
void InitGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH); //平滑着色
glEnable(GL_DEPTH_TEST); //深度测试
glEnable(GL_CULL_FACE); //只渲染某一面
glFrontFace(GL_CCW); //逆时针正面
glEnable(GL_TEXTURE_2D); //启用2D纹理映射
//载入纹理图像:
ReadImage();
//生成纹理对象:
glGenTextures(1, &texture);
}
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture); //绑定纹理:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //支持4字节对齐
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //S方向上贴图
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); //T方向上贴图
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //放大纹理过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //缩小纹理过滤方式
glTexImage2D(GL_TEXTURE_2D, 0, 3, imgWidth, imgHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imgBuf); //载入纹理:
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
glEnable(GL_TEXTURE_2D); //启用2D纹理映射
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小
{
glViewport(0, 0, width, height);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("opengl");
InitGL();
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
//glutKeyboardFunc(keyboard);
//glutMouseWheelFunc(mouse_wheel);
//glutIdleFunc(idle);
glutMainLoop();
return 0;
}
最后显示的情况如下:

另外注意最后需要释放资源:
glDeleteTextures(1, &texture);
if (imgBuf)
{
delete[] imgBuf;
imgBuf = nullptr;
}
OpenGL显示图片的更多相关文章
- (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片
转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...
- 如何使用SOIL在VS2012的 C++环境下显示图片
先看下效果. 这是一个很无聊的功能....首先说下,我做这个功能的初衷并不是为了实现在控制台中显示图片...(这貌似很无聊) 而是因为自己想做用C做一个游戏:http://q.cnblogs.com/ ...
- img只显示图片一部分 或 css设置背景图片只显示图片指定区域
17:14 2016/3/22img只显示图片一部分 或 css设置背景图片只显示图片指定区域 background-position: 100% 56%; 设置背景图片显示图片的哪个坐标区域,图片左 ...
- python将图片转换为Framebuffer裸数据格式(终端显示图片)
要在ubuntu终端显示图片或者在板子的LCD显示图片,Framebuffer是一个简单易用的接口,直接写入像素信息即可. 但普通的图片带有头部信息或者编码格式不同,直接送入Framebuffer是显 ...
- Chrome 控制台新玩法-console显示图片以及为文字加样式
有兴趣的同学可以文章最后的代码复制贴到控制台玩玩. Go for Code 在正常模式下,一般只能向console 控制台输出简单的文字信息.但为了把信息输出得更优雅更便于阅读,除了cosole.lo ...
- Qt自适应大小显示图片,添加菜单
由于后面的图像处理需要UI,OpenCV自带也不怎么会,MFC实在懒得学的.听同学说Qt不错,就用Qt做UI了. 本文主要介绍三个内容:在Qt Creator中使用OpenCV2.Qt中自适应显示图片 ...
- EmguCV控件Emgu.CV.UI.ImageBox及C# picturebox显示图片连续刷新出现闪烁问题
在上一篇里,EmguCV(OpenCV)实现高效显示汉字及叠加 实现了视频叠加及显示,但存在问题,就是 Emgu.CV.UI.ImageBox及C# picturebox显示图片时都会出现闪烁,尤其 ...
- 显示图片的(自定义)吐司Toast
一般我们提示的时候都是直接提示文字的,其实Toast也可以显示图片 常用方法 Toast.makeText(context,text,duration)这返回一个Toast对象 toast.setDu ...
- python 读取并显示图片的两种方法
在 python 中除了用 opencv,也可以用 matplotlib 和 PIL 这两个库操作图片.本人偏爱 matpoltlib,因为它的语法更像 matlab. 一.matplotlib 1. ...
随机推荐
- Arctext.js - 基于 CSS3 & jQuery 的文本弯曲效果
Arctext.js 是基于 Lettering.js 的文本旋转插件,根据设置的旋转半径准确计算每个字母的旋转弧度并均匀分布.虽然 CSS3 也能够实现字符旋转效果,但是要让安排每个字母都沿着弯曲路 ...
- 精致3D图片切换效果,最适合企业产品展示
这是一个精致的立体图片切换效果,特别适合企业产品展示,可立即用于实际项目中.支持导航和自动播放功能, 基于 CSS3 实现,推荐使用最新的 Chrome,Firefox 和 Safari 浏览器浏览效 ...
- java并发编程实践学习(2)--对象的组合
先验条件(Precondition):某些方法包含基于状态的先验条件.例如,不能从空队列中移除一个元素,在删除元素前队列必须处于非空状态.基于状态的先验条件的操作成为依赖状态操作. 在单线程中,如果某 ...
- React-Native 给客户端来个「同音词模糊搜索」
APP上线一段时间有用户反应说不方便找东西,其实APP的数据不大也就三四百条而以,但受限于手机端展示区域太小.信息大爆炸,大家也基本上不会去记具体的名称都是根据模糊的印象进行搜索而且现在大家基本都用拼 ...
- [转]俞敏洪:我和马云就差了8个字... [来自: news.mbalib.com]
我和马云差了 8 个字:越败越战,愈挫愈勇. 马云,我真的非常的佩服他,首先佩服他的是他跟我有同样的经历,我考了 3 年才考上了大学:他也是考了 3 年.我比他还要幸运一点,我考上的是北大的本科,马云 ...
- html5画布的旋转效果
keleyi.htm的代码如下: <!DOCTYPE HTML> <html> <head> <title>html旋转画布-柯乐义</title ...
- ajaxfileupload asp.net 的简单使用
本人菜鸟,第一次写博客,不会排版,只是记录工作中常用的东西 ajaxfileupload.js源码: http://www.rczjp.cn/HTML/110420/20113620053635.ht ...
- 不需要写代码,文件夹右键cmd定位指定目录
引子 这篇文章其实本来不是这样的,因为我用C#的代码实现了一个程序,后面才突然发现,我太傻太天真了,明明不需要写程序和写代码的,结果自己把自己二住了. 我们来看看效果图. 由于,我自己的原因,这个功能 ...
- ASP.NET中的随机密码生成
第一种方法:用.NET中的 Sytem.Guid.NewGuid().ToString() 生成,实际上是对一个128bit数字的十六进制输出.生成的字符由0-9和a-z这几种字符组成,也可能会有“- ...
- 身份证验证合法性js--已验证
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...