• Advertisement

Archived

This topic is now archived and is closed to further replies.

Screenshots: how to save screen to TGA?

This topic is 5619 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need to a make snapshot of my opengl program (a simple 3dplotter i made to see mathematical algorithm outputs) How do i save the screen to a graphic format file? I there any available code to make this? PLEASE?! How can i take the screen matrix pixels to write them to disk? Can anybody help me?? THANKS!!! LOTS OF THANKS!

Share this post


Link to post
Share on other sites
Advertisement
So long as you are using opengl it''s very easy. First you need to have a function to create a tga (or whatever format you want) file. The following is the source for doing just that. This is copied out of OpenGL Game Programming (except the comments), no copyright infringement intended.

int WriteTGAFile(char *filename, short int width, short int
height, unsigned char *imageData)
{
unsigned char byteSkip;
short int shortSkip;
unsigned char imageType;
int colorMode;
unsigned char colorSwap;
int imageIdx;
unsigned char bitDepth;
long imageSize;
FILE *filePtr; // you must #include stdio.h to use
this

filePtr = fopen(filename, "wb");
if (!filePtr)
{
fclose(filePtr);
return 0;
}
imageType = 2; // rgb, uncompressed
bitDepth = 24; // 24 bits per pel
colorMode = 3;
byteSkip = 0;
shortSkip = 0;

fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr);
fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr);
fwrite(&imageType, sizeof(unsigned char), 1, filePtr);
fwrite(&shortSkip, sizeof(short int), 1, filePtr);
fwrite(&shortSkip, sizeof(short int), 1, filePtr);
fwrite(&byteSkip, sizeof(unsigned char), 1, filePtr);
fwrite(&shortSkip, sizeof(short int), 1, filePtr);
fwrite(&shortSkip, sizeof(short int), 1, filePtr);
fwrite(&width, sizeof(short int), 1, filePtr);
fwrite(&height, sizeof(short int), 1, filePtr);
fwrite(&bitDepth, sizeof(unsigned char), 1, filePtr);

imageSize = width * height * colorMode;
for (imageIdx = 0; imageIdx < imageSize; imageIdx +=
colorMode)
{
colorSwap = imageData[imageIdx];
imageData[imageIdx] = imageData[imageIdx + 2];
imageData[imageIdx + 2] = colorSwap;
}

fwrite(imageData, sizeof(unsigned char), imageSize, filePtr);
fclose(filePtr);
return 1;
}

Ok, that will (when you give it some data to work with) write a tga. Now for the function to save the screen. This is again copied out of OpenGL Game Programming. The code here assumes a 800 x 600 window, if you are using one of a different size, change the numbers to match you resolution.

void SaveScreenshot()
{
imageData = malloc(800*600*3);
memset(imageData, 0, 800*600*3);
glReadPixels(0, 0, 799, 599, GL_RGB, GL_UNSIGNED_BYTE,
imageData);

WriteTGAFile("writeout.tga", 800, 600, (unsigned char*)
imageData);

free(imageData);
}

There you go, hope that helps.

Share this post


Link to post
Share on other sites
If you''re using windows, you can use alt-print screen to save a screenshot to the clipboard, and copy the image from your clipboard into any paint program.


Mike

"The state is that great fiction by which everyone tries to live at the expense of everyone else." - Frederick Bastiat, The Law

"Capitalism between consenting adults is a basic human right." - Unknown

Share this post


Link to post
Share on other sites
quote:

glReadPixels(0, 0, 799, 599, GL_RGB, GL_UNSIGNED_BYTE, imageData);


This is not correct if you want to read a 800x600 image. Third and fourth argument should be 800 and 600, since that''s how many pixels you want to read.

Share this post


Link to post
Share on other sites
Thanks!!!!!
This is just i needed!
THANKS Dragon88!

Now i am greedy! I want to know if there is a rutine availaible which writes PNG graphics files...

Thanks!



Share this post


Link to post
Share on other sites
quote:
Original post by Brother Bob
[quote]
glReadPixels(0, 0, 799, 599, GL_RGB, GL_UNSIGNED_BYTE, imageData);


This is not correct if you want to read a 800x600 image. Third and fourth argument should be 800 and 600, since that''s how many pixels you want to read.

You''re forgetting something. Computers count zero as the first number, thus starting at 0, 0, and copying through 799, 599 will encompass exactly 800x600 pixels.

Share this post


Link to post
Share on other sites
Nope, 800 and 600 are the width and height of the image, not the coordinates of the opposite corner.

From the OpenGL specification:

void ReadPixels( int x, int y, sizei width, sizei height,
enum format, enum type, void *data );

... width and height are the width and height, respectively, of the pixel rectangle to be
drawn.

Share this post


Link to post
Share on other sites
Way to go on correcting the guy four times in a row. Talk about redundancy. Did by some chance you all posted in unison, or did the last few of you not bother to read the rest of the posts cuz you wanted to put your 2 cents in?

How come more people don''t use DevIL/OpenIL? It''s got fancy features that do stuff like this, along with tons of really cool imaging effects.

Share this post


Link to post
Share on other sites
quote:

You''re forgetting something. Computers count zero as the first number, thus starting at 0, 0, and copying through 799, 599 will encompass exactly 800x600 pixels.


You''re the one that''s forgetting something; whate the third and fourth parameter really mean. They mean width and height of the image you want to read. So 800 and 600 will read a 800x600 image.

Share this post


Link to post
Share on other sites
I copied the code to my proyect...
This routine have the funny misbehaviour of inverting RGB colors..
The colors are ordered RBG instead of RGB...
I fixed change WriteTGAFile() as follow:
(correct)
for (imageIdx = 0; imageIdx < imageSize; imageIdx +=colorMode)
{
colorSwap = imageData[imageIdx];
imageData[imageIdx ] = imageData[imageIdx + 2];
imageData[imageIdx + 2] = imageData[imageIdx + 1];
imageData[imageIdx + 1] = colorSwap;
}

Instead of:
(wrong)
for (imageIdx = 0; imageIdx < imageSize; imageIdx +=colorMode)
{
colorSwap = imageData[imageIdx];
imageData[imageIdx] = imageData[imageIdx + 2];
imageData[imageIdx + 2] = colorSwap;
}

Share this post


Link to post
Share on other sites

  • Advertisement