如何在 SDL 2 中获取并保存 BMP 屏幕截图?
Posted
技术标签:
【中文标题】如何在 SDL 2 中获取并保存 BMP 屏幕截图?【英文标题】:How do I take and save a BMP screenshot in SDL 2? 【发布时间】:2013-12-12 13:31:40 【问题描述】:仅使用给定的 SDL_Window* 和 SDL_Renderer*,我如何在 SDL 2.0 中创建和保存屏幕截图?
【问题讨论】:
【参考方案1】:下面是一个将屏幕截图保存到 SDL 2 中的函数,该屏幕截图取自我目前正在编写的库。
bool saveScreenshotBMP(std::string filepath, SDL_Window* SDLWindow, SDL_Renderer* SDLRenderer)
SDL_Surface* saveSurface = NULL;
SDL_Surface* infoSurface = NULL;
infoSurface = SDL_GetWindowSurface(SDLWindow);
if (infoSurface == NULL)
std::cerr << "Failed to create info surface from window in saveScreenshotBMP(string), SDL_GetError() - " << SDL_GetError() << "\n";
else
unsigned char * pixels = new (std::nothrow) unsigned char[infoSurface->w * infoSurface->h * infoSurface->format->BytesPerPixel];
if (pixels == 0)
std::cerr << "Unable to allocate memory for screenshot pixel data buffer!\n";
return false;
else
if (SDL_RenderReadPixels(SDLRenderer, &infoSurface->clip_rect, infoSurface->format->format, pixels, infoSurface->w * infoSurface->format->BytesPerPixel) != 0)
std::cerr << "Failed to read pixel data from SDL_Renderer object. SDL_GetError() - " << SDL_GetError() << "\n";
delete[] pixels;
return false;
else
saveSurface = SDL_CreateRGBSurfaceFrom(pixels, infoSurface->w, infoSurface->h, infoSurface->format->BitsPerPixel, infoSurface->w * infoSurface->format->BytesPerPixel, infoSurface->format->Rmask, infoSurface->format->Gmask, infoSurface->format->Bmask, infoSurface->format->Amask);
if (saveSurface == NULL)
std::cerr << "Couldn't create SDL_Surface from renderer pixel data. SDL_GetError() - " << SDL_GetError() << "\n";
delete[] pixels;
return false;
SDL_SaveBMP(saveSurface, filepath.c_str());
SDL_FreeSurface(saveSurface);
saveSurface = NULL;
delete[] pixels;
SDL_FreeSurface(infoSurface);
infoSurface = NULL;
return true;
干杯! -尼尔
【讨论】:
pixels = NULL;
应该是delete[] pixels;
,否则数组会泄露。【参考方案2】:
如果您使用带有 SDL2 的 OpenGL,您可以直接调用 glReadPixels
,而不是使用信息表面和渲染器。这是一个示例(没有错误检查)。
void Screenshot(int x, int y, int w, int h, const char * filename)
unsigned char * pixels = new unsigned char[w*h*4]; // 4 bytes for RGBA
glReadPixels(x,y,w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, w, h, 8*4, w*4, 0,0,0,0);
SDL_SaveBMP(surf, filename);
SDL_FreeSurface(surf);
delete [] pixels;
这里是 SDL wiki page,其中包含设置窗口和 OpenGL 上下文的示例。
编辑:如果您想复制/粘贴此 sn-p,请记住添加一些错误检查
【讨论】:
感谢代码示例! invert the surface vertically 之后效果很好。 还要考虑到endianness :)【参考方案3】:void Screenshot(int x, int y, int w, int h, const char * filename)
Uint32 rmask, gmask, bmask, amask;
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
unsigned char * pixels = new unsigned char[w*h*4]; // 4 bytes for RGBA
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, w, h, 8*4, w*4, rmask, gmask, bmask, amask);
SDL_SaveBMP(surf, filename);
SDL_FreeSurface(surf);
delete [] pixels;
【讨论】:
请阅读有关如何提问的指南:***.com/help/how-to-ask。具体来说,描述您的问题、您的尝试以及遇到的困难。以上是关于如何在 SDL 2 中获取并保存 BMP 屏幕截图?的主要内容,如果未能解决你的问题,请参考以下文章