Does anyone know of a way to capture an OpenGL image (from framebuffer?) and convert it to a standard image format (.jpg, .gif, etc)?
ksnapshot doesn’t seem to be able to do this…
Thanks,
B
Does anyone know of a way to capture an OpenGL image (from framebuffer?) and convert it to a standard image format (.jpg, .gif, etc)?
ksnapshot doesn’t seem to be able to do this…
Thanks,
B
/*
- screenshot.h
- Copyright (C) 2001 Ryan T. Sammartino
- Shaw Communications
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA.
*/#ifndef SCREENSHOT_H
#define SCREENSHOT_H
typedef enum {
SCREENSHOT_PPM,
SCREENSHOT_TGA,
SCREENSHOT_BMP,
} SCREENSHOT_FORMAT;/*
- SCREENSHOT_Take will dump the given portion of the GL framebuffer to
- the given filename. The file will be overwritten
- x, y, width, height definre the rectangle to capture.
- 0, 0 is the upper-left corner
- The image will be stored in the given format
- Returns negative on failure, zero on success
*/
int SCREENSHOT_Take(int x, int y, int width, int height,
const char *fname,
SCREENSHOT_FORMAT format);
#endif // !SCREENSHOT_H
/*
- screenshot.c
- Routines for taking screen shots from GL
- Copyright (C) 2001 Ryan T. Sammartino
- Shaw Communications
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA.
*/#include <stdio.h>
#include <malloc.h>
#include <GL/gl.h>#include “screenshot.h”
static int SCREENSHOT_WriteBMP(const char *fname,
const unsigned char image,
int w, int h)
{
/ See http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/BMP.txt */
struct BMPHeader {
unsigned short type;
unsigned int size;
unsigned short res1;
unsigned short res2;
unsigned int offset;
} attribute_((packed)) header;
struct BMPInfo {
unsigned int size;
unsigned int width;
unsigned int height;
unsigned short planes;
unsigned short bit_count;
unsigned int comp;
unsigned int sizeImage;
unsigned int x_pels_per_meter;
unsigned int y_pels_per_meter;
unsigned int clr_used;
unsigned int clr_important;
} attribute((packed)) info;
FILE *fp;
int ret = 0;/* Open file */ fp = fopen(fname, "wb"); if (!fp) { fprintf(stderr, "Unable to open %s for writing
",
fname);
ret = -1;
} else {
/* Header */
header.type = ‘B’ | ‘M’ << 8;
header.size = sizeof(header) + sizeof(info) + w * h * 3;
header.res1 = header.res2 = 0;
header.offset = sizeof(header) + sizeof(info);
info.size = sizeof(info);
info.width = w;
info.height = h;
info.planes = 1;
info.bit_count = 24;
info.comp = 0;
info.sizeImage = w * h * 3;
info.x_pels_per_meter = info.y_pels_per_meter = 0;
info.clr_used = 0;
info.clr_important = 0;fwrite(&header, sizeof(header), 1, fp); fwrite(&info, sizeof(info), 1, fp); fwrite(image, sizeof(unsigned char), h*w*3, fp); } if (fp) { fclose(fp); } return ret;
}
static int SCREENSHOT_WriteTGA(const char *fname,
const unsigned char *image,
int w, int h)
{
int i;
FILE fp;
int ret = -1;
/ See http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/TGA.txt for spec */
struct TGAHeader {
unsigned char idfield_len;
unsigned char cmap_type;
unsigned char image_type;
unsigned char cmap_spec[5];
unsigned char x_orig[2];
unsigned char y_orig[2];
unsigned char width[2];
unsigned char height[2];
unsigned char pixel_size;
unsigned char image_desc;
} attribute((packed)) header;/* Open file */ fp = fopen(fname, "wb"); if (!fp) { fprintf(stderr, "Unable to open %s for writing
",
fname);
ret = -1;
} else {
/* Construct header /
header.idfield_len = 0;
header.cmap_type = 0;
header.image_type = 2;
for (i = 0; i < 5; i++) {
header.cmap_spec[i] = 0;
}
for (i = 0; i < 2; i++) {
header.x_orig[i] = 0;
header.y_orig[i] = 0;
}
/ Lo bits /
header.width[0] = w & 0xFF;
/ Hi bits */
header.width[1] = (w >> 8) & 0xFF;
header.height[0] = h & 0xFF;
header.height[1] = (h >> 8) & 0xFF;
header.pixel_size = 24;
header.image_desc = 0;/* Output header */ fwrite(&header, sizeof(header), 1, fp); /* Output image */ fwrite(image, sizeof(unsigned char), w*h*3, fp); } if (fp) { fclose(fp); } return ret;
}
static int SCREENSHOT_WritePPM(const char *fname,
const unsigned char *image,
int w, int h)
{
unsigned char *row;
int i;
FILE *fp;
int ret = 0;/* Open file */ fp = fopen(fname, "wb"); if (!fp) { fprintf(stderr, "Unable to open %s for writing
",
fname);
ret = -1;
} else {
/* Output header */
fprintf(fp,
"P6
#Screenshot %s
%d %d
%d
",
fname, w, h, 255);/* GL returns the data upside down */ for (i = h - 1; i >= 0; i--) { row = (unsigned char*)image + w * i * 3; fwrite(row, sizeof(unsigned char), w*3, fp); } } if (fp) { fclose(fp); } return ret;
}
/*
SCREENSHOT_Take will dump the given portion of the GL framebuffer to
the given filename
x, y, width, height define the rectangle to capture.
The image will be stored in the given format
Returns negative on failure, zero on success
*/
int SCREENSHOT_Take(int x, int y, int width, int height,
const char *fname,
SCREENSHOT_FORMAT format)
{
unsigned char *image = NULL;
int ret = 0;/* Reserve some memory /
image = (unsigned char)malloc(sizeof(unsigned char)widthheight*3);
if (!image) {
fprintf(stderr,
"Unable to allocate image buffer
");
ret = -1;
} else {
switch(format) {
case SCREENSHOT_PPM:
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WritePPM(fname, image, width, height);
break;
case SCREENSHOT_TGA:
glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WriteTGA(fname, image, width, height);
break;
case SCREENSHOT_BMP:
glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WriteBMP(fname, image, width, height);
break;
default:
fprintf(stderr, "Invalid format %d
", format);
ret = -1;
break;
}
}if (image) {
free(image);
}return ret;
}
[This message has been edited by rts (edited 03-23-2002).]
[This message has been edited by rts (edited 03-23-2002).]
i try to use your class but it give me an error into the gl.h file…why?
I am a newbie here so sorry if my question will be so stupid.
thx a lot
Well, whats the error?
Old GLman
Gimp usually does a good job, TNT2 with driver 1.0-29601.0-2960
This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.