#37760 - kajic - Tue Mar 15, 2005 11:41 pm
UPDATE2:
I updated the code so that output format and the frameskipping rate can be specified from the terminal. Also added a backup function so that one can easily backup the old animation file when generating another one.
UPDATE:
I just came to the bright idea of testing another program to open the gif generated by my program. Guess what? It worked perfectly! Ive been sitting for 6 hours trying to fix an error not there... one thing is for sure, I wont be using Kuickshow anymore.
Hi, first of all I hope I am placing the thread in the right forum. I was considering between the Coding, the C/C++, and this one and finally decided this was the one I should use.
I've made a little program that can generate a series of png images from an animation created by an algorithm. This part works perfectly using some GD functions. Then I decided I wanted a way to create an animated gif directly instead of merging the pngs into a gif using the ImageMagick convert program together with a shell script.
Well, sufficient to say I tried and even though I get a lot of data written to the output gif when I try to view it I only see a black image... no animation, no nothing. I am hoping I have done some easy to see mistake in my coding and that someone can point out why I am not getting the desired result.
Btw, the "tool" Im making will be used to make nice sprites for a gba game I am thinking to start on. You might say I could just as easy make the animations with photoshop but the thing is my skills in that area are equal to zero so I trust more in my ability to algorithmically create animations :)
Anyway, here is my code... I hope you will find it easy to read/understand!
Last edited by kajic on Thu Mar 17, 2005 1:07 am; edited 1 time in total
I updated the code so that output format and the frameskipping rate can be specified from the terminal. Also added a backup function so that one can easily backup the old animation file when generating another one.
UPDATE:
I just came to the bright idea of testing another program to open the gif generated by my program. Guess what? It worked perfectly! Ive been sitting for 6 hours trying to fix an error not there... one thing is for sure, I wont be using Kuickshow anymore.
Hi, first of all I hope I am placing the thread in the right forum. I was considering between the Coding, the C/C++, and this one and finally decided this was the one I should use.
I've made a little program that can generate a series of png images from an animation created by an algorithm. This part works perfectly using some GD functions. Then I decided I wanted a way to create an animated gif directly instead of merging the pngs into a gif using the ImageMagick convert program together with a shell script.
Well, sufficient to say I tried and even though I get a lot of data written to the output gif when I try to view it I only see a black image... no animation, no nothing. I am hoping I have done some easy to see mistake in my coding and that someone can point out why I am not getting the desired result.
Btw, the "tool" Im making will be used to make nice sprites for a gba game I am thinking to start on. You might say I could just as easy make the animations with photoshop but the thing is my skills in that area are equal to zero so I trust more in my ability to algorithmically create animations :)
Anyway, here is my code... I hope you will find it easy to read/understand!
Code: |
#include<gd.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define WIDTH 180 #define HEIGHT 120 #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+1)) 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) { /* put the pixel to the image */ gdImageSetPixel(im, x_pos, y_pos, gdImageColorResolve(im, red, green, blue)); } /* draws a line from from_x, from_t to to_x, to_y */ void drawLine(gdImagePtr im, int from_x, int from_y, int to_x, int to_y, int red, int green, int blue) { /* draw the line */ gdImageLine(im, from_x, from_y, to_x, to_y, gdImageColorResolve(im, red, green, blue)); } /* 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 9; would produce a gif animation where every tenth frame is used. \nExample: %s png 0; 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; for (frame=0; frame<HEIGHT; frame++) { /* put pixels to image */ int i; for (i=0; i<WIDTH; i++) putPixel(im, i, frame, red, 0, 0); /* output the image */ makeFile(im, outType, frame, frameSkip); /* change the color of the next row */ red++; } srand(time(NULL)); int r; int x=WIDTH/2, y=HEIGHT/2; for (frame=0; frame<HEIGHT/2; frame++) { r = (rand() % (HEIGHT/2))-(HEIGHT/4); x+=r; r = (rand() % (HEIGHT/2))-(HEIGHT/4); y+=r; red = (rand() % WIDTH); drawLine(im, WIDTH/2, HEIGHT/2, x, y, red, 0, 0); makeFile(im, outType, frame, frameSkip); x=WIDTH/2; y=HEIGHT/2; } for (frame=0; frame<HEIGHT; frame++) { /* put pixels to image */ int i; for (i=0; i<WIDTH; i++) putPixel(im, i, frame, 0, 0, 0); /* output the image */ makeFile(im, outType, frame, frameSkip); /* change the color of the next row */ red++; } /* end of the testing algorithm */ /* close gif */ if (!strcmp(outType, "gif")) closeGif(); /* destroy image */ gdImageDestroy(im); return 0; } |
Last edited by kajic on Thu Mar 17, 2005 1:07 am; edited 1 time in total