Sign in to follow this  
CSharper

Screen capture with C++

Recommended Posts

Hi fellows Can someone answer me where can I read something about screen capture with c++? I don't want the source code, just an article that explains how I can do this. Thanks a lot

Share this post


Link to post
Share on other sites
Impossible with C++ alone.

You'll need to investigate an API to use. Win32 (GDI) for windows,
There are other ways to do it using OpenGL or DirectX, if you are already using those in your project.

Share this post


Link to post
Share on other sites
Hi CSharper, it is so cool to print your application screen so I have your answer if you are using OpenGL.To Print the screen, you will need the right API, I found some old code snippet which allows you to grab a OpenGL screen, then save it as a TGA file. I remember finding it on the web last year, testing and anaylysing it and it works. Try this class as it is so easy to port into your application if you are using OpenGL...

shot.h

/*
Class Name:

CTGALoader.

This class loads a tga texture into this object.
*/



#ifndef CTGALOADER_H
#define CTGALOADER_H

// Remember to place all your GL/system header files that you will need to run class function

class CTGALoader
{
public:
CTGALoader(); // Constructor.
~CTGALoader(); // Destructor.

bool LoadTGAFile(char *filename); // Load a .tga image file.
void SaveTGAScreenShot(char *filename,
int width,
int height); // Save a .tga screen shot.
void FreeImage(); // Delete a image.

unsigned int ID; // ID used for generating the textures in OpenGl.
int imageWidth; // Width of a texture.
int imageHeight; // Height of a texture.

protected:
void GenerateTexture(); // Generate a texture in OpenGL.
bool LoadTGA(char *filename); // Load a tga image.
bool WriteTGA(char *file, short int width,
short int height,
unsigned char *image); // Write a tga file.

unsigned char *image; // Texture image.
bool textureExist; // This will be used if the image was loaded.
int type; // Image format.
};

#endif




Shot.cpp


/*
Class Name:

CTGALoader.

*/



#include"shot.h"


CTGALoader::CTGALoader()
{
// Give everything default values.
image = 0;
textureExist = false;
type = 0;
}


CTGALoader::~CTGALoader()
{
FreeImage(); // Delete all images and dynamic memory.
}


bool CTGALoader::LoadTGAFile(char *file)
{
if(textureExist)
FreeImage();

if(!LoadTGA(file))
return false;

// Make sure the image loaded.
if(image == 0)
{
return false;
}

GenerateTexture();

textureExist = true;

return true;
}


void CTGALoader::GenerateTexture()
{
// Generate the texture and text the id to the images id.
glGenTextures(1, &ID);

// Here we bind the texture and set up the filtering.
glBindTexture(GL_TEXTURE_2D, ID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

gluBuild2DMipmaps(GL_TEXTURE_2D, type, imageWidth, imageHeight,
type, GL_UNSIGNED_BYTE, image);
glTexImage2D(GL_TEXTURE_2D, 0, type, imageWidth, imageHeight,
0, type, GL_UNSIGNED_BYTE, image);
}


bool CTGALoader::LoadTGA(char* file)
{
FILE *pfile;
unsigned char tempColor; // This will change the images from BGR to RGB.
unsigned char uselessChar; // This will be used to hold char data we dont want.
short int uselessInt; // This will be used to hold int data we dont want.
int colorMode; // If this is 3 then its in RGB, 4 is RGBA.
long tgaSize; // Image size.
long index; // Used in the for loop.
unsigned char imageTypeCode;
unsigned char bitCount;


// Open the image and read in binary mode.
pfile = fopen(file, "rb");

// check if the file opened.
if (!pfile)
return false;

// Read in the two useless values.
fread(&uselessChar, sizeof(unsigned char), 1, pfile);
fread(&uselessChar, sizeof(unsigned char), 1, pfile);

// Read the image type, 2 is color, 4 is is greyscale.
fread(&imageTypeCode, sizeof(unsigned char), 1, pfile);

// We only want to be able to read in color or greyscale .tga's.
if ((imageTypeCode != 2) && (imageTypeCode != 3))
{
fclose(pfile);
return false;
}


// Get rid of 13 bytes of useless data.
fread(&uselessInt, sizeof(short int), 1, pfile);
fread(&uselessInt, sizeof(short int), 1, pfile);
fread(&uselessChar, sizeof(unsigned char), 1, pfile);
fread(&uselessInt, sizeof(short int), 1, pfile);
fread(&uselessInt, sizeof(short int), 1, pfile);


// Get the image width and height.
fread(&imageWidth, sizeof(short int), 1, pfile);
fread(&imageHeight, sizeof(short int), 1, pfile);

// Get the bit count.
fread(&bitCount, sizeof(unsigned char), 1, pfile);

// Get rid of 1 byte of useless data.
fread(&uselessChar, sizeof(unsigned char), 1, pfile);

// If the image is RGB then colorMode should be 3 and RGBA would
// make colorMode equal to 4. This will help in our loop when
// we must swap the BGR(A) to RGB(A).
colorMode = bitCount / 8;

// Determine the size of the tga image.
tgaSize = imageWidth * imageHeight * colorMode;

// Allocate memory for the tga image.
image = (unsigned char*)malloc(sizeof(unsigned char)*tgaSize);

// Read the image into imageData.
fread(image, sizeof(unsigned char), tgaSize, pfile);

// This loop will swap the BGR(A) to RGB(A).
for (index = 0; index < tgaSize; index += colorMode)
{
tempColor = image[index];
image[index] = image[index + 2];
image[index + 2] = tempColor;
}

// Close the file where your done.
fclose(pfile);

if(bitCount == 32)
type = GL_RGBA;
else
type = GL_RGB;

// return true to satisfy our if statement (load successful).
return true;
}


void CTGALoader::FreeImage()
{
// When the application is done delete all dynamically allocated memory.
if(image)
{
free(image);
image = 0;
textureExist = false;
type = 0;
}
}


bool CTGALoader::WriteTGA(char *file, short int width, short int height, unsigned char *outImage)
{
// To save a screen shot is just like reading in a image. All you do
// is the opposite. Istead of calling fread to read in data you call
// fwrite to save it.

FILE *pFile; // The file pointer.
unsigned char uselessChar; // used for useless char.
short int uselessInt; // used for useless int.
unsigned char imageType; // Type of image we are saving.
int index; // used with the for loop.
unsigned char bits; // Bit depth.
long Size; // Size of the picture.
int colorMode;
unsigned char tempColors;

// Open file for output.
pFile = fopen(file, "wb");

// Check if the file opened or not.
if(!pFile) { fclose(pFile); return false; }

// Set the image type, the color mode, and the bit depth.
imageType = 2; colorMode = 3; bits = 24;

// Set these two to 0.
uselessChar = 0; uselessInt = 0;

// Write useless data.
fwrite(&uselessChar, sizeof(unsigned char), 1, pFile);
fwrite(&uselessChar, sizeof(unsigned char), 1, pFile);

// Now image type.
fwrite(&imageType, sizeof(unsigned char), 1, pFile);

// Write useless data.
fwrite(&uselessInt, sizeof(short int), 1, pFile);
fwrite(&uselessInt, sizeof(short int), 1, pFile);
fwrite(&uselessChar, sizeof(unsigned char), 1, pFile);
fwrite(&uselessInt, sizeof(short int), 1, pFile);
fwrite(&uselessInt, sizeof(short int), 1, pFile);

// Write the size that you want.
fwrite(&width, sizeof(short int), 1, pFile);
fwrite(&height, sizeof(short int), 1, pFile);
fwrite(&bits, sizeof(unsigned char), 1, pFile);

// Write useless data.
fwrite(&uselessChar, sizeof(unsigned char), 1, pFile);

// Get image size.
Size = width * height * colorMode;

// Now switch image from RGB to BGR.
for(index = 0; index < Size; index += colorMode)
{
tempColors = outImage[index];
outImage[index] = outImage[index + 2];
outImage[index + 2] = tempColors;
}

// Finally write the image.
fwrite(outImage, sizeof(unsigned char), Size, pFile);

// close the file.
fclose(pFile);

return true;
}


// This will save a screen shot to a file.
void CTGALoader::SaveTGAScreenShot(char *filename, int w, int h)
{
unsigned char *outputImage = 0;

// Allocate the neccessary memory.
outputImage = (unsigned char*)malloc(w * h * 3);

// Clear the variable.
memset(outputImage, 0, w * h * 3);

// You use the glReadPixels() to read every pixel on the screen
// that you specify. You must use one less than each size.
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, outputImage);

// Call our WriteTGA() function to write the tga.
WriteTGA(filename, w, h, (unsigned char*)outputImage);

// Clear the allocated memory.
free(outputImage);
}




All I have to say is you are using OpenGL, cut and past the code shown below and configure the way you want it into your project. It will work as i have tried it many times experimenting. I hope you enjoy..
Regards

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this