OpenGL将当前屏幕保存为bmp/png/jpg文件

最近OpenGL程序中需要用到将当前屏幕图像保存为jpg文件,在网上查了很多资料,大部分都是保存为bmp文件,很难找到保存为jpg文件的说明与示例,通过查找资料以及自己的试验将其总结如下:


将当前屏幕图像保存为bmp文件

//抓取窗口中的像素
void grab()
{
	FILE* pDummyFile;
	FILE* pWritingFile;
	GLubyte* pPixelData;
	GLubyte BMP_Header[BMP_Header_Length];
	GLint i, j;
	GLint PixelDataLength;
	// 计算像素数据的实际长度
	i = WIN_WIDTH * 3; // 得到每一行的像素数据长度
	while( i%4 != 0 ) // 补充数据,直到 i是的倍数
		++i; // 本来还有更快的算法,
	// 但这里仅追求直观,对速度没有太高要求
	PixelDataLength = i * WIN_HEIGHT;
	// 分配内存和打开文件
	pPixelData = (GLubyte*)malloc(PixelDataLength);
	if( pPixelData == 0 )
		exit(0);
	pDummyFile = fopen("whole.bmp", "rb");//从一个正确的bmp文件中读取前54个字节,修改其中的宽度和高度信息,就可以得到新的文件头
	if( pDummyFile == 0 )
		exit(0);

	pWritingFile = fopen("test.bmp", "wb");

	if( pWritingFile == 0 )
		exit(0);
	// 读取像素
	// GL_UNPACK_ALIGNMENT指定OPenGL如何从数据缓冲区中解包图像数据
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
	glReadPixels(0, 0, WIN_WIDTH, WIN_HEIGHT, GL_BGR_EXT, GL_UNSIGNED_BYTE, pPixelData);
	// 把 whole.bmp 的文件头复制为新文件的文件头
	fread(BMP_Header, sizeof(BMP_Header), 1, pDummyFile);
	fwrite(BMP_Header, sizeof(BMP_Header), 1, pWritingFile);
	fseek(pWritingFile, 0x0012, SEEK_SET);
	i = WIN_WIDTH;
	j = WIN_HEIGHT;
	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);
}


将当前屏幕图像保存为png文件

void grab()
{
    unsigned char *mpixels =new unsigned char[WIDTH * HEIGHT * 4];//WIDTH和HEIGHT为所要保存的屏幕图像的宽度与高度
    glReadBuffer(GL_FRONT);
    glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, mpixels);
    glReadBuffer(GL_BACK);
    for(int i=0; i<(int)WIDTH*HEIGHT*4; i+=4)
    { 
        mpixels[i] ^= mpixels[i+2] ^= mpixels[i] ^= mpixels[i+2];
    }
    FIBITMAP* bitmap =FreeImage_Allocate(WIDTH, HEIGHT, 32, 8, 8, 8);

    for(int y = 0 ;y < FreeImage_GetHeight(bitmap); y++)
    {
        BYTE *bits = FreeImage_GetScanLine(bitmap, y);
        for(int x = 0; x < FreeImage_GetWidth(bitmap); x++)
        {
            bits[0] = mpixels[(y*WIDTH+x)*4+0];
            bits[1] = mpixels[(y*WIDTH+x)*4+1];
            bits[2] = mpixels[(y*WIDTH+x)*4+2];
            bits[3] = 255;
            bits += 4;
        }

    }
    bool bSuccess = FreeImage_Save(FIF_PNG, bitmap, "test.png", PNG_DEFAULT);
    FreeImage_Unload(bitmap);
}

将当前屏幕图像保存为jpg文件

void grab()
{
	unsigned char *mpixels = new unsigned char[WIDTH * HEIGHT * 3];
    glReadBuffer(GL_FRONT);
    glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, mpixels);
    glReadBuffer(GL_BACK);
    for(int i = 0; i < (int)WIDTH*HEIGHT*3; i += 3)
    {   
        mpixels[i] ^= mpixels[i+2] ^= mpixels[i] ^= mpixels[i+2];
    }
    FIBITMAP* bitmap = FreeImage_Allocate(WIDTH, HEIGHT, 24, 8, 8, 8);

    for(int y = 0 ; y < FreeImage_GetHeight(bitmap); y++)
    {
        BYTE *bits = FreeImage_GetScanLine(bitmap, y);
        for(int x = 0 ; x < FreeImage_GetWidth(bitmap); x++)
        {
            bits[0] = mpixels[(y*WIDTH+x) * 3 + 0];
            bits[1] = mpixels[(y*WIDTH+x) * 3 + 1];
            bits[2] = mpixels[(y*WIDTH+x) * 3 + 2];
            bits += 3;
        }

    }

	FreeImage_Save(FIF_JPEG, bitmap, "test.jpg", JPEG_DEFAULT);

    FreeImage_Unload(bitmap);
}


在OpenGL程序中调用grab()函数即可……


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值