opengl中捕获bmp图像时如何设定保存图像的位置
我在网上找了一段捕获屏幕图像的代码(下面),插入到自己的程序中后,想通过键盘输入捕获图像。但是屏幕只是闪了一下,图像并没有生成,我想问一下,如何设置保存图像的位置?还有,在这段程序中,图像捕获后被存在了哪里呢?
void grab(void)
{
FILE* pDummyFile;
FILE* pWritingFile;
GLubyte* pPixelData;
GLubyte BMP_Header[BMP_Header_Length];
GLint i, j;
GLint PixelDataLength;
int WindowWidth = 640;
int WindowHeight = 480;
// 计算像素数据的实际长度
i = WindowWidth * 3; // 得到每一行的像素数据长度
while( i%4 != 0 ) // 补充数据,直到i是的倍数
++i; // 本来还有更快的算法,
// 但这里仅追求直观,对速度没有太高要求
PixelDataLength = i * WindowHeight;
// 分配内存和打开文件
pPixelData = (GLubyte*)malloc(PixelDataLength);
if( pPixelData == 0 )
exit(0);
pDummyFile = fopen("dummy.bmp", "rb");
if( pDummyFile == 0 )
exit(0);
pWritingFile = fopen("grab.bmp", "wb");
if( pWritingFile == 0 )
exit(0);
// 读取像素
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glReadPixels(0, 0, WindowWidth, WindowHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);
// 把dummy.bmp的文件头复制为新文件的文件头
fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile);
fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile);
fseek(pWritingFile, 0x0012, SEEK_SET);
i = WindowWidth;
j = WindowHeight;
fwrite(&i, sizeof(i), 1, pWritingFile);
fwrite(&j, sizeof(j), 1, pWritingFile);
// 写入像素数据
fseek(pWritingFile, 0, SEEK_END);
fwrite(pPixelData, PixelDataLength, 1, pWritingFile);
// 释放内存和关闭文件
fclose(pDummyFile);
fclose(pWritingFile);
free(pPixelData);
}
恶魔娘阿洛
12 years ago
Answers
在“grab.bmp”前添想要保存的文件路径名应该就可以了。否则的话就会存在你源文件所在的目录。
最后,这个函数的位置要放对。
// ---Sun_earth.cpp---
#include <gl/glut.h>
#define WIDTH 400
#define HEIGHT 400
//
// grab_screen.cpp
#define WindowWidth 400
#define WindowHeight 400
#include <gl/glut.h>
#include <stdio.h>
#include <stdlib.h>
// 函数 grab
// 抓取窗口中的像素
// 假设窗口宽度为 WindowWidth,高度为 WindowHeight
#define BMP_Header_Length 54
void grab(void)
{
FILE* pDummyFile;
FILE* pWritingFile;
GLubyte* pPixelData;
GLubyte BMP_Header[BMP_Header_Length];
GLint i, j;
GLint PixelDataLength;
// 计算像素数据的实际长度
i = WindowWidth * 3; // 得到每一行的像素数据长度
while( i%4 != 0 ) // 补充数据,直到 i是的倍数
{
++i;
} // 本来还有更快的算法,
// 但这里仅追求直观,对速度没有太高要求
PixelDataLength = i * WindowHeight;
// 分配内存和打开文件
pPixelData = (GLubyte*)malloc(PixelDataLength);
if( pPixelData == 0 )
{
exit(0);
}
pDummyFile = fopen("dummy.bmp", "rb");
if( pDummyFile == 0 )
{
exit(0);
}
pWritingFile = fopen("grab.bmp", "wb");
if( pWritingFile == 0 )
{
exit(0);
}
// 读取像素
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glReadPixels(0, 0, WindowWidth, WindowHeight,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);
// 把 dummy.bmp 的文件头复制为新文件的文件头
fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile);
fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile);
fseek(pWritingFile, 0x0012, SEEK_SET);
i = WindowWidth;
j = WindowHeight;
fwrite(&i, sizeof(i), 1, pWritingFile);
fwrite(&j, sizeof(j), 1, pWritingFile);
// 写入像素数据
fseek(pWritingFile, 0, SEEK_END);
fwrite(pPixelData, PixelDataLength, 1, pWritingFile);
// 释放内存和关闭文件
fclose(pDummyFile);
fclose(pWritingFile);
free(pPixelData);
}
//
static GLfloat angle = 0.0f;
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 创建透视效果视图
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, -010.0, -0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
// 定义太阳光源,它是一种白色的光源
{
GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
// 定义太阳的材质并绘制太阳
{
GLfloat sun_mat_ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_diffuse[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
GLfloat sun_mat_shininess = 0.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);
glutSolidSphere(2.0, 40, 32);
}
// 定义地球的材质并绘制地球
{
GLfloat earth_mat_ambient[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_diffuse[] = {0.0f, 0.0f, 0.5f, 1.0f};
GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat earth_mat_shininess = 30.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission);
glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
glRotatef(angle, 0.0f, -1.0f, 0.0f);
glTranslatef(5.0f, 0.0f, 0.0f);
glutSolidSphere(2.0, 40, 32);
}
glutSwapBuffers();
grab();
}
void myIdle(void)
{
angle += 1.0f;
if( angle >= 360.0f )
angle = 0.0f;
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("OpenGL光照演示");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}
这是我以前照着网上打的一个程序,没有添加按键控制,希望对你有帮助。
Leptons
answered 12 years ago