Creating starfield images
Below is the C program used to create a b/w 8 bits per channel, 1 channel, RAW format output starfield images.
/***************************************************************
HEADER FILE CODE
**************************************************************/
/***************************************************************
This program was created by Timothy Fox on January 29, 2002
My email: special_effect.geo@yahoo.com
My website: www.oocities.org/hollywood/theater/1991
**************************************************************/
#ifndef _STAR_FIELD
#define _STAR_FIELD
//widescreen format 2700x1149 pixels
#define STARFIELD_IMAGE_HEIGHT 1149 //image height in pixels
#define STARFIELD_IMAGE_WIDTH 2700 //image width in pixels
// 2000 stars creates a very dense starfield
#define NUMBER_STARS 2000 //number of stars we produce
#define XSMALL 0
#define SMALL 1
#define LARGE 3
#define MEDIUM 2
#define XLARGE 4
#ifdef _STAR_FIELD_DECLARE
//where do we store the output starfield?
char output_starfield_filename[] = "Krusty:starfields:starfield.out";
//percents of 100 of the total for each star size to create. Array element 0 is
//the XSmall size up through array element 4 which is XLarge sized stars
float star_percents[5] = { 0.15, 0.4, 0.25, 0.1, 0.1 };
unsigned char **output_starfield_image = NULL;
//the 3D array which holds the actual images of each star at each size
unsigned char stars_array[5][8][8] = {
{{1,1,1,1,1,1,1,1}, //XSmall star
{1,1,1,1,1,1,1,1},
{1,1,46,46,46,1,1,1},
{1,1,46,255,46,1,1,1},
{1,1,46,46,46,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1}},
{{1,1,1,1,1,1,1,1}, //Small star
{1,1,1,1,1,1,1,1},
{1,1,46,134,134,46,1,1},
{1,1,134,255,255,134,1,1},
{1,1,134,255,255,134,1,1},
{1,1,46,134,134,46,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1}},
{{1,1,1,1,1,1,1,1}, //Medium star
{1,1,46,134,46,1,1,1},
{1,46,134,255,134,46,1,1},
{1,134,255,255,255,134,1,1},
{1,46,134,255,134,46,1,1},
{1,1,46,134,46,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1}},
{{1,1,1,30,1,1,1,1}, //Large star
{1,34,134,202,134,34,1,1},
{1,134,255,255,255,134,1,1},
{30,202,255,255,255,202,30,1},
{1,134,255,255,255,134,1,1},
{1,34,134,202,134,34,1,1},
{1,1,1,30,1,1,1,1},
{1,1,1,1,1,1,1,1}},
{{1,1,1,20,20,1,1,1}, //XLarge star
{1,36,117,192,192,117,36,1},
{1,117,255,255,255,255,117,1},
{21,192,255,255,255,255,192,21},
{21,192,255,255,255,255,192,21},
{1,117,255,255,255,255,117,1},
{1,36,117,192,192,117,36,1},
{1,1,1,20,20,1,1,1}}
};
#else
extern unsigned char stars_array[5][8][8];
extern float star_percents[5];
extern char output_starfield_filename[];
extern unsigned char **output_starfield_image;
#endif /* _STAR_FIELD_DECLARE */
#endif /* _STAR_FIELD */
/***************************************************************
SOURCE FILE CODE
**************************************************************/
#define _STAR_FIELD_DECLARE
#include "stdio.h"
#include "stdlib.h"
#include "fcntl.h"
#include "time.h"
#include "star_field.h"
void main()
{
FILE *output_ptr = NULL;
int n_written, row, col, row_coord, col_coord, r,c, starfield_row, starfield_col;
int found_star_location, star, number_stars_to_create, star_size;
if (STARFIELD_IMAGE_HEIGHT * STARFIELD_IMAGE_WIDTH > 1000*1000*100)
{
printf("Your starfield is larger than 100MB in size.\n");
exit(1);
}
//get 2D array space to hold our entire output starfield image
printf("Getting the starfield image array space...\n");
output_starfield_image = (unsigned char **) malloc(sizeof(unsigned char *) *
STARFIELD_IMAGE_HEIGHT);
output_starfield_image[0] = (unsigned char *) malloc(sizeof(unsigned char) *
(STARFIELD_IMAGE_HEIGHT * STARFIELD_IMAGE_WIDTH));
//assign the pointer array to point to the various rows of the array
for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++)
output_starfield_image[row] = output_starfield_image[0] + (row*STARFIELD_IMAGE_WIDTH);
//make sure the output starfield image starts out all black
printf("Blacking out the starfield image...\n");
for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++)
for(col=0; col < STARFIELD_IMAGE_WIDTH; col++)
output_starfield_image[row][col] = 0;
//now lets create all the stars in the image
//first we initialize our random number generator
srand((unsigned) time(NULL));
printf("Placing stars in the starfield image...\n");
//lets process stars from extra small up to extra large
for (star_size = XSMALL; star_size < = XLARGE; star_size++)
{
//how many stars should we create for the selected star size
number_stars_to_create = star_percents[star_size] * NUMBER_STARS;
//lets try to create the required number of stars of the selected size
for (star = 1; star < = number_stars_to_create; star++)
{
//we start by saying we haven't yet found the stars location on the image
found_star_location = 0;
//while we have not yet found the stars ending location
while (!found_star_location)
{
//lets figure out where the star should be placed
col_coord = (rand() % (STARFIELD_IMAGE_WIDTH - 5));
row_coord = (rand() % (STARFIELD_IMAGE_HEIGHT - 4));
//is the stars center location off the images left or top edges?
//if so then lets find another location for the star
if ((col_coord < 3) || (row_coord < 4))
continue;
//now lets figure out if we have already placed another star at this location
//if so lets select another location
if ((output_starfield_image[row_coord-4][col_coord-3] > 0) || //top left
(output_starfield_image[row_coord-4][col_coord+4] > 0) || //top right
(output_starfield_image[row_coord+3][col_coord-3] > 0) || //bottom left
(output_starfield_image[row_coord+3][col_coord+4] > 0)) //bottom right
continue;
found_star_location = 1; //otherwise we have found a new star location
//now lets plop a new star into the starfield
for (starfield_row = row_coord-4, r=0; starfield_row < = row_coord + 3;
starfield_row++, r++)
for (starfield_col = col_coord-3, c=0; starfield_col < = col_coord + 4;
starfield_col++, c++)
output_starfield_image[starfield_row][starfield_col] =
stars_array[star_size][r][c];
}
}
}
printf("Searching starfield image for flag pixels to return to black...\n");
//now lets go through the entire image and return pixel values of 1 back to 0
for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++)
for(col=0; col < STARFIELD_IMAGE_WIDTH; col++)
if (output_starfield_image[row][col] == 1)
output_starfield_image[row][col] = 0;
//now lets write our starfield out to disk
output_ptr = fopen(output_starfield_filename, "wb"); //open an output file
if (output_ptr == NULL)
{
free(output_starfield_image[0]);
free(output_starfield_image);
return;
}
printf("Writing output starfield file %s...\n", output_starfield_filename);
//go through the starfield array and output each row of the image
for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++)
{
//write a row of the image out to the disk file
n_written = fwrite((void *) &(output_starfield_image[row][0]),
sizeof(unsigned char), STARFIELD_IMAGE_WIDTH, output_ptr);
//were we successful at writing out the correct number of pixels?
if (n_written != STARFIELD_IMAGE_WIDTH)
{
printf("wrong number of starfield column pixels written to disk\n");
printf("row %d (base 0), number of columns attemped = %d\n", row, n_written);
fclose(output_ptr);
free(output_starfield_image[0]);
free(output_starfield_image);
return;
}
}
fclose(output_ptr);
output_ptr = NULL;
free(output_starfield_image[0]); //free the pixel array
free(output_starfield_image); //free the pointer array
printf("The program has finished.\n");
}
Last Updated: Feburary 4, 2002
HTML URL: http://www.oocities.org/~special_effect/starfield_generator.html
E-Mail: special_effect.geo@yahoo.com or click here