OpenGL使用FreeImage保存屏幕截图

说明

  • 给现有模拟平台集成保存当前时刻OpenGL渲染屏幕截图
  • 环境:Windows 10,Visual Studio 2019,C++

准备

下载FreeImage库,http://freeimage.sourceforge.net/download.html

打开sln,编译FreeImageLib这个项目(设为启动项),根据debug/release版本选择编译。

环境配置:

2019安装目录:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333
ps:路径会因版本不同稍有区别

  • 首先把FreeImage.h 头文件拷贝至在"VS安装目录"/VC/include/
  • 把FreeImage.lib静态库拷贝到"VS安装目录"**/VC/lib/**中;
  • 最后,把FreeImage.dll动态链接库放在应用程序的目录下,一般为VS工程的bin目录

使用前加上

1
#pragma comment(lib, "FreeImage.lib")

使用

实际需求的代码实现片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
std::string exportPath = FileSystem::normalizePath(m_outputPath + "/img");
FileSystem::makeDirs(exportPath);
//glReadPixels
std::string picName = "pic_";
picName = picName + std::to_string(m_frameCounter) + ".png";
std::string exportPicName = FileSystem::normalizePath(exportPath + "/" + picName);

int width = 1280;
int height = 960;

unsigned char* mpixels = new unsigned char[width * height * 4];
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, mpixels);
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, exportPicName.c_str(), PNG_DEFAULT);
FreeImage_Unload(bitmap);
}

网上的保存为jpg参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
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);
}