How do I take and save a BMP screenshot in SDL 2?

后端 未结 2 1070
不思量自难忘°
不思量自难忘° 2021-02-07 09:09

Using just a given SDL_Window* and SDL_Renderer*, how can I create and save a screenshot in SDL 2.0?

相关标签:
2条回答
  • 2021-02-07 09:52

    If you are using OpenGL with SDL2 you can call glReadPixels directly instead of using the info surface and renderer. Here is an example (without error checking).

    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;
    }
    

    Here's the SDL wiki page with an example of setting up the window and an OpenGL context.

    Edit: If you are tempted to copy/paste this snippet, remember to add some error checking

    0 讨论(0)
  • 2021-02-07 10:05

    Below is a function for saving a screenshot in SDL 2 taken from a library I'm currently writing.

    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;
    }
    

    Cheers! -Neil

    0 讨论(0)
提交回复
热议问题