So, we've played with structs, arrays, files, functions, pointers… how about putting all that together and making something a bit more tangible? Like, say, an image file that can be viewed!
Here's some code, let's walk through it:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <gd.h> #include <gdfontl.h> // color values // #define BLACK 0 #define GRAY 1 #define VIOLET 2 #define INDIGO 3 #define BLUE 4 #define GREEN 5 #define YELLOW 6 #define ORANGE 7 #define RED 8 #define WHITE 9 #define DARKGREEN 10
We start with some preprocessor stuff… note there are some new header files being used we haven't utilized before, and then a section of #define directives setting up some symbols whose names we can associate with colors (but aren't yet actually mapped to actual colors).
Next up (same file, all of this example is in one file):
int main() { FILE *out; char outfile[] = "image.png"; gdImagePtr img; unsigned int color[11]; unsigned short int wide, high, x; wide = 800; high = 600;
We see a new “type” here, a gdImagePtr… this is likely some typedef'ed struct. The rest should all be variable types you are familiar with.
We then do some initialization and set up our colors:
img = gdImageCreate(wide, high); // My GD color definitions // color[BLACK] = gdImageColorAllocate(img, 0x00, 0x00, 0x00); color[BLUE] = gdImageColorAllocate(img, 0x00, 0x00, 0xFF); color[GREEN] = gdImageColorAllocate(img, 0x00, 0xFF, 0x00); color[DARKGREEN] = gdImageColorAllocate(img, 0x33, 0x6B, 0x00); color[RED] = gdImageColorAllocate(img, 0xFF, 0x00, 0x00); color[GRAY] = gdImageColorAllocate(img, 0xCC, 0xCC, 0xCC); color[WHITE] = gdImageColorAllocate(img, 0xFF, 0xFF, 0xFF);
gdImageColorAllocate(), a function in the GD library, takes 4 parameters (the gdImagePtr we declared above), and the 3 bytes of RGB values for the color we want.
Now let's fill in our image with a solid background:
// Fill in canvas with white background // gdImageFilledRectangle(img, 0, 0, wide, high, color[WHITE]);
What color is the background going to be? If we wanted to change it to the color “green”, how could we do that?
Drawing a border around the edge of our image:
// Draw a thin red border around the outside // gdImageLine(img, 0, 0, wide-1, 0, color[RED]); gdImageLine(img, wide-1, 0, wide-1, high-1, color[RED]); gdImageLine(img, wide-1, high-1, 0, high-1, color[RED]); gdImageLine(img, 0, high-1, 0, 0, color[RED]);
And drawing a shape (a green rectangle– note that you'll have trouble seeing it if you've changed your background to green):
// Draw a green filled rectangle in the bottom-left (inset slightly) gdImageFilledRectangle(img, 10, high-100, wide-10, high-10, color[GREEN]);
How about a pacman-esque circle?
// Draw a blue pacman-esque filled circle // gdImageFilledArc(img, wide/2, high/2, high/2-50, high/2-50, 45, 315, color[BLUE], gdArc);
We can even display text!
// Display the GD API URL across the top // x = (strlen("http://www.boutell.com/gd/manual2.0.33.html")*gdFontGetLarge()->w); x = x / 2; x = (wide / 2) - x; gdImageString(img, gdFontGetLarge(), x, 10, "http://www.boutell.com/gd/manual2.0.33.html", color[BLACK]);
The URL being displayed is to a page with the GD API, which you will most certainly want to bookmark and reference, as there are MANY more functions available to us in the GD library.
Finally before we are done, we need to wrap things up appropriately:
As we are using the GD library, we need to link against it:
lab46:~/src$ gcc -o gdintro gdintro.c -lgd lab46:~/src$
You'd run it as normal, and should just get your prompt back:
lab46:~/src$ ./gdintro lab46:~/src$
If you do an ls after running it, you should see a new file created “image.png”.
We can view this through our lab46 web space by first copying it there:
lab46:~/src$ cp image.png ~/public_html/ lab46:~/src$
And then pointing a web browser at our image:
Obviously, replace lab46username with YOUR Lab46 username.
Go ahead and change some things (colors, add new shapes, lines, etc.) and practice recompiling, running, copying the new image file, and viewing the changes.