#include<gd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define WIDTH 320
#define HEIGHT 240
#define GIF_NAME "animation.gif"
/* determine if a file exists */
int fileExists(char *filename) {
/* declare file */
FILE *file;
/* try to open file */
if ((file = fopen(filename, "r")) == NULL)
return 0;
/* as the file exists we must close it */
fclose(file);
return 1;
}
/* add the frame to the gif-animation specified by GIF_NAME. if no such
animation exists one will be created and before we add the frame the
header of the gif will be written to the created file */
void makeGif(gdImagePtr im) {
/* declare output file */
FILE *outFile;
/* if there exists no animatione we will create one and write its header */
if (!fileExists(GIF_NAME)) {
/* open file */
outFile = fopen(GIF_NAME, "wb");
/* write the header */
gdImageGifAnimBegin(im, outFile, 0, 0);
/* close the file */
fclose(outFile);
}
/* open file im append mode */
outFile = fopen(GIF_NAME, "ab");
/* add the frame */
gdImageGifAnimAdd(im, outFile, 1, 0, 0, 1, gdDisposalNone, NULL);
/* close the file */
fclose(outFile);
}
/* terminate the gif-animation specified by GIF_NAME. this is done
by adding a semicolon to the end of the file. */
void closeGif() {
/* declare output file */
FILE *outFile;
/* open file in append mode */
outFile = fopen(GIF_NAME, "ab");
gdImageGifAnimEnd(outFile);
}
/* save the frame at im to a png-file */
void makePng(gdImagePtr im, int frame) {
/* declare output file */
FILE *outFile;
char frameName[11];
frameName[0] = '\0';
/* convert frame int to string */
sprintf(frameName, "%d", frame);
/* append the extension */
strcat(frameName, ".png\0");
/* open output file */
outFile = fopen(frameName, "wb");
/* output the image */
gdImagePng(im, outFile);
/* close file */
fclose(outFile);
}
/* if the current frame shouldnt be skipped we can either call
upon makePng for it to create the frame OR makeGif so that
the frame can be added to the gif-animation specified by
GIF_NAME */
void makeFile(gdImagePtr im, char *type, int frame, int frameSkipping) {
/* check if the frame we are at should be outputed */
if (frame % frameSkipping)
return;
/* check what type of image we want to output */
if (!strcmp(type, "gif"))
makeGif(im);
else if (!strcmp(type, "png"))
makePng(im, frame);
}
/* sets the given pixel in the frame im to the given color */
void putPixel(gdImagePtr im, int x_pos, int y_pos, int red, int green, int blue) {
int color;
/* set the drawing color */
color = gdImageColorResolve(im, red, green, blue);
/* put a pixel to the image */
gdImageSetPixel(im, x_pos, y_pos, color);
}
/* create a frame with the given dimensions/background color
note: the color of the background is also made transparent */
gdImagePtr createImage(gdImagePtr im, int width, int height, int red, int green, int blue) {
/* allocate the image */
im = gdImageCreate(width, height);
/* allocate the background color, as it is the first color allocated in a new
image it will be used as background */
int bg;
bg = gdImageColorAllocate(im, red, green, blue);
return im;
}
/* create a backup of the animation specified by GIF_NAME */
void backupAnimation(void) {
if (fileExists(GIF_NAME)) {
char newName[200];
newName[0] = '\0';
int n;
for (n=1; n>0; n++) {
sprintf(newName, "old.%d." GIF_NAME, n);
if (!fileExists(newName))
n=-1;
}
rename(GIF_NAME, newName);
}
}
int main(int argc, char *argv[]) {
/* check if the correct number of arguments have been suplied */
if (argc != 3) {
/* print usage message */
printf("Usage: %s [string png/gif] [int frameSkip where frameSkip>0]\nExample: %s gif 10; would produce a gif animation where every tenth frame is used. \nExample: %s png 1; would produce one png image for each frame. \nNote: The first frame can't be skipped. \n", argv[0], argv[0], argv[0]);
return 20;
}
/* set output type */
char outType[3];
strcpy(outType, argv[1]);
/* set frameSkip value */
int frameSkip;
frameSkip = atoi(argv[2]); /* this will cause an floating point exception if argv[2] cant be converted to and int */
/* backup the animation file if it already exists */
if (!strcmp(outType, "gif"))
backupAnimation();
/* declare the image */
gdImagePtr im;
/* create the image */
im = createImage(im, WIDTH, HEIGHT, 0, 0, 0);
/* a simple algorithm indended for testing */
int frame;
int red=0, green=0, blue=0;
for (frame=0; frame<HEIGHT; frame++) {
/* put pixels to image */
int i;
for (i=0; i<WIDTH; i++)
putPixel(im, i, frame, red, green, blue);
/* output the image */
makeFile(im, outType, frame, frameSkip);
/* change the color of the next row */
red++;
}
/* close gif */
if (!strcmp(outType, "gif"))
closeGif();
/* destroy image */
gdImageDestroy(im);
return 0;
}
|