仅使用给定的SDL_Window *和SDL_Renderer *,如何在SDL 2.0中创建和保存屏幕截图?
答案 0 :(得分:11)
以下是从我正在编写的库中保存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;
}
干杯! -Neil
答案 1 :(得分:7)
如果您使用带有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上下文的示例。
答案 2 :(得分:1)
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;
}