Simple screenshot example

Hi Guys,

I’ve done some googling - maybe I’m searching for the wrong thing.

I’d really appreciate it if someone could list the call sequence to
achieve this:

  • create a 200x200 window and show it on the right hand side of the screen.
  • set a timer for 1/2 second to repeat:
    • take a snapshot of 200x200 pixels of screen from top-left
    • show these pixels in the new window

I’d like to help with the docs process, so once I get this working -
where should I put a working example?

Great work - everyone involved.

Thanks,
Jack

If you’re using SDL 1.2 + SDL_Surface, you could do this every 500ms:

void take_snapshot( SDL_Surface *source ) {
SDL_SaveBMP( source, “your_snapshot_name.bmp” );
}

// …
take_snapshot( SDL_GetVideoSurface() ); // Snapshot the video_surface

If you’re using SDL 1.3/2.0 with the Renderer, you’ll want to use the
following in combination:
void *pixel_data = NULL;
SDL_QueryTexturePixelshttp://wiki.libsdl.org/moin.cgi/SDL_QueryTexturePixels(
your_sdl_texture, &pixel_data, your_pitch_calculation );

From there, you can toss your texture into an SDL_Surface, and use the same
method as in 1.2
take_snapshot( Your_Texture_Converted_To_Surface );

If you’re using OpenGL, you’ll want to do some googling on that - I found
two promising hits:-
http://eonstrife.wordpress.com/2007/06/02/taking-a-screenshot-from-an-opengl-application/

http://stackoverflow.com/questions/5844858/how-to-take-screenshot-in-opengl

I hope that helps,
-Alex

On Wed, Jun 20, 2012 at 7:17 AM, Jack Andrews wrote:

Hi Guys,

I’ve done some googling - maybe I’m searching for the wrong thing.

I’d really appreciate it if someone could list the call sequence to
achieve this:

  • create a 200x200 window and show it on the right hand side of the
    screen.
  • set a timer for 1/2 second to repeat:
  • take a snapshot of 200x200 pixels of screen from top-left
  • show these pixels in the new window

I’d like to help with the docs process, so once I get this working -
where should I put a working example?

Great work - everyone involved.

Thanks,
Jack


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Also, a huge improvement would be to be able to
save as a JPG or other compressed format. A BMP will save to a large
file.

You can search this very list for various implementations of
save-to-png functionality, for example


PNG has compression which might be quite sufficient for your needs, and
those functions are usually very small and copy-pastable.On Wed, 20 Jun 2012 22:31:41 -0700 “Trev” wrote:


driedfruit

I currently use this to take a screenshot:

Code:
int w=gState->GetWindowWidth();
int h=gState->GetWindowHeight();

#define kNumColorComponents 3 //RGB=3, RGBA=4
SDL_Surface temp = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8kNumColorComponents, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 );

char * pixels = new char [kNumColorComponents * w * h];
if(kNumColorComponents==3)
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
else if(kNumColorComponents==4)
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

SDL_LockSurface( temp );
for (int i = 0 ; i < h ; i++)
std::memcpy( ((char ) temp->pixels) + temp->pitch * i, pixels + kNumColorComponents * w * (h-i - 1), wkNumColorComponents );
SDL_UnlockSurface( temp );
delete [] pixels;

SDL_SaveBMP(temp, (char*)Path.c_str());
SDL_FreeSurface(temp);

It is missing some functionality. I would like to be able to resize the screenshot to specific input dimensions, but I’m not sure the best way to do that. Also, a huge improvement would be to be able to save as a JPG or other compressed format. A BMP will save to a large file. My application window is set to 1084x813 and the output file as a BMP is about 2.6 MB, because 1084x813x3=2,643,930. I couldn’t think of any good reason to save the Alpha values for a screenshot. With basic JPG compression, the same image is about 16% of that. When I get some time, I will make sure saving to a JPEG is possible. People expect to be able to save to that image format, and rightly so in my opinion.

With regard to your specific request, it seems like you want more of a mirror than a proper screenshot. You could just re-render the screen in its own viewport, or you could make a SDL_Surface of the window and use that. Both have disadvantages and advantages. With a full re-render, you could remove specific things you wanted to remove, like parts of the interface. With just ripping an SDL_Surface from the window, you wouldn’t have to re-render everything.