int main () { bitmap_t fruit; int x; int y; /* Create an image. */ fruit.width = 100; fruit.height = 100; fruit.pixels = calloc (sizeof (pixel_t), fruit.width * fruit.height); for (y = 0; y < fruit.height; y++) { for (x = 0; x < fruit.width; x++) { pixel_t * pixel = pixel_at (& fruit, x, y); pixel->red = pix (x, fruit.width); pixel->green = pix (y, fruit.height); } } /* Write the image to a file 'fruit.png'. */ save_png_to_file (& fruit, "fruit.png"); return 0; }
void net_to_png( net_t *n, char *file_path, int scale ) { assert( n != NULL ); bitmap_t pic; pic.width = n->cols * scale; pic.height = n->rows * scale; pic.pixels = calloc( sizeof(pixel_t), pic.width * pic.height ); if( pic.pixels == NULL ) print_error("alloc"); int i; int x1; int y1 = 0; pixel_t *pixel; // One cell is 'scale'x'scale' size for( unsigned int y = 0; y < pic.height; y+= scale ) { x1 = 0; for( unsigned int x = 0; x < pic.width; x+= scale ) { i = ( n->cols * y1 + x1 ); if( n->vec[i] == 1 ) { for( int a = 0; a < scale; a++ ) { for( int b = 0; b < scale; b++ ) { // White pixel = pixel_at( &pic, x + a, y + b ); pixel->red = 255; pixel->green = 255; pixel->blue = 255; } } } x1++; } y1++; } save_png_to_file( &pic, file_path ); free(pic.pixels); }
/* Write "bitmap" to a PNG file specified by "path"; returns 0 on success, non-zero on error. */ int save_png_to_file (Bitmap *bitmap, const char *path) { FILE * fp; png_structp png_ptr = NULL; png_infop info_ptr = NULL; size_t x, y; png_bytep *row_pointers = NULL; /* "status" contains the return value of this function. At first it is set to a value which means 'failure'. When the routine has finished its work, it is set to a value which means 'success'. */ int status = -1; /* The following number is set by trial and error only. I cannot see where it it is documented in the libpng manual. */ int pixel_size = 3; int depth = 8; fp = fopen (path, "wb"); if (! fp) { goto fopen_failed; } png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { goto png_create_write_struct_failed; } info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL) { goto png_create_info_struct_failed; } /* Set up error handling. */ if (setjmp (png_jmpbuf (png_ptr))) { goto png_failure; } /* Set image attributes. */ png_set_IHDR (png_ptr, info_ptr, bitmap->width, bitmap->height, depth, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* Initialize rows of PNG. */ row_pointers = (png_bytep*) png_malloc(png_ptr, bitmap->height*sizeof(png_byte *)); for (y = 0; y < bitmap->height; ++y) { png_byte *row = (png_byte *)png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size); row_pointers[y] = row; for (x = 0; x < bitmap->width; ++x) { WPixel* pixel = pixel_at(bitmap, x, y); *row++ = pixel->red; *row++ = pixel->green; *row++ = pixel->blue; } } /* Write the image data to "fp". */ png_init_io (png_ptr, fp); png_set_rows (png_ptr, info_ptr, row_pointers); png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); /* The routine has successfully written the file, so we set "status" to a value which indicates success. */ status = 0; for (y = 0; y < bitmap->height; y++) { png_free (png_ptr, row_pointers[y]); } png_free (png_ptr, row_pointers); png_failure: png_create_info_struct_failed: png_destroy_write_struct (&png_ptr, &info_ptr); png_create_write_struct_failed: fclose (fp); fopen_failed: return status; }
int draw_waveform(struct wave* w, struct image* img, int style) { int middle, upward, downward; int j, i; int ch0, ch1; struct waveform_data* d; middle = (img->height)/2; upward = (img->height)/2; downward = (img->height)/2; d = compute_waveform(w, img->width); // These cases are ugly, but it's not much prettier to unify them. if(style == 1) { for (j=0; j<(img->width); j++) { /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->b = 255; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255-i*255/ch0; } for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = 255; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255-i*255/ch1; } } } if(style == 2) { for (i=0; i<(img->height); i++) { for (j=0; j<(img->width); j++) { pixel_at(img, i, j)->r = 222; pixel_at(img, i, j)->g = 240; pixel_at(img, i, j)->b = 255; pixel_at(img, i, j)->a = 255; } } for (j=0; j<(img->width); j++) { double fading = 0.7; /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->r = pow(i, fading)*pow(ch0, 1-fading)*222/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->g = pow(i, fading)*pow(ch0, 1-fading)*240/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->b = 255; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255; } for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = pow(i, fading)*pow(ch1, 1-fading)*222/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->g = pow(i, fading)*pow(ch1, 1-fading)*240/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->b = 255; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255; } } } if(style == 3) { for (j=0; j<img->width; j++) { for (i=0; i<(img->height)/2; i++) { set_pixel_at(img, i, j, 222, 240, 255, 255); } for (i=(img->height)/2; i<(img->height); i++) { set_pixel_at(img, i, j, 255, 127, 0, 255); } } for (j=0; j<(img->width); j++) { double fading = 0.7; /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); fading = 0.5; for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->r = pow(i, fading)*pow(ch0, 1-fading)*222/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->g = pow(i, fading)*pow(ch0, 1-fading)*240/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->b = 127+pow(i, fading)*pow(ch0, 1-fading)*128/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255; } fading = 0.7; for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = 127+pow(i, fading)*pow(ch1, 1-fading)*128/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->g = pow(i, fading)*pow(ch1, 1-fading)*127/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->b = 000; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255; } } } if(style == 4) { for (j=0; j<img->width; j++) { for (i=0; i<(img->height)/2; i++) { set_pixel_at(img, i, j, 222, 240, 255, 255); } for (i=(img->height)/2; i<(img->height); i++) { set_pixel_at(img, i, j, 0, 0, 127, 255); } } for (j=0; j<(img->width); j++) { double fading = 0.7; /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->r = pow(i, fading)*pow(ch0, 1-fading)*222/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->g = pow(i, fading)*pow(ch0, 1-fading)*240/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->b = 127+pow(i, fading)*pow(ch0, 1-fading)*128/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255; } for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = 222-pow(i, fading)*pow(ch1, 1-fading)*222/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->g = 240-pow(i, fading)*pow(ch1, 1-fading)*240/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->b = 255-pow(i, fading)*pow(ch1, 1-fading)*128/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255; } } } if(style == 5) { for (j=0; j<img->width; j++) { for (i=0; i<(img->height)/2; i++) { set_pixel_at(img, i, j, 0, 0, 127, 255); } for (i=(img->height)/2; i<(img->height); i++) { set_pixel_at(img, i, j, 0, 0, 127, 255); } } for (j=0; j<(img->width); j++) { double fading = 0.8; /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->r = 222-pow(i, fading)*pow(ch0, 1-fading)*222/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->g = 240-pow(i, fading)*pow(ch0, 1-fading)*240/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->b = 255-pow(i, fading)*pow(ch0, 1-fading)*128/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255; } for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = 222-pow(i, fading)*pow(ch1, 1-fading)*222/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->g = 240-pow(i, fading)*pow(ch1, 1-fading)*240/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->b = 255-pow(i, fading)*pow(ch1, 1-fading)*128/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255; } } } if(style == 6) { for (j=0; j<img->width; j++) { for (i=0; i<(img->height)/2; i++) { set_pixel_at(img, i, j, 222, 240, 255, 255); } for (i=(img->height)/2; i<(img->height); i++) { set_pixel_at(img, i, j, 222, 240, 255, 255); } } for (j=0; j<(img->width); j++) { double fading = 0.5; /* Should probably scale by max and median out. */ ch0 = d->upper_array[j]*upward/(d->ch0_max); ch1 = d->lower_array[j]*downward/(d->ch1_max); for (i=0; i<ch0; i++) { pixel_at(img, MAX(middle-i-1, 0), j)->r = pow(i, fading)*pow(ch0, 1-fading)*222/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->g = pow(i, fading)*pow(ch0, 1-fading)*240/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->b = 127+pow(i, fading)*pow(ch0, 1-fading)*128/ch0; pixel_at(img, MAX(middle-i-1, 0), j)->a = 255; } for (i=0; i<ch1; i++) { pixel_at(img, MIN(middle+i, (img->height)-1), j)->r = pow(i, fading)*pow(ch1, 1-fading)*222/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->g = pow(i, fading)*pow(ch1, 1-fading)*240/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->b = 127+pow(i, fading)*pow(ch1, 1-fading)*128/ch1; pixel_at(img, MIN(middle+i, (img->height)-1), j)->a = 255; } } } waveform_data_free(d); return 0; }
int write_png(image_t* img, const char* file_name) { size_t x, y; png_structp png_ptr; png_infop info_ptr; png_byte** row_pointers; int depth = 8; int pixel_size = 3; /* init the file and structs */ FILE* fp = fopen(file_name, "wb"); if (!fp) { return fail(fp, "Failed to open file for writing"); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { png_destroy_write_struct(&png_ptr, &info_ptr); return fail(fp, "png_create_write_struct failed"); } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, &info_ptr); return fail(fp, "png_create_info_struct failed"); } /* setup error handling */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return fail(fp, "error"); } /* set image attributes */ png_set_IHDR(png_ptr, info_ptr, img->width, img->height, depth, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* init rows */ row_pointers = png_malloc(png_ptr, sizeof(png_byte*) * img->height); for (y = 0; y < img->height; ++y) { png_byte* row = png_malloc(png_ptr, sizeof(uint8_t) * img->width * pixel_size); row_pointers[y] = row; for (x = 0; x < img->width; ++x) { pixel_t* pixel = pixel_at(img, x, y); *row++ = pixel->red; *row++ = pixel->green; *row++ = pixel->blue; } } /* write data to file */ png_init_io(png_ptr, fp); png_set_rows(png_ptr, info_ptr, row_pointers); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); /* cleanup */ for (y = 0; y < img->height; y++) { png_free(png_ptr, row_pointers[y]); } png_free(png_ptr, row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return 0; }
void Metafile::toPNG(PMEMPNG accum, int width, int height, const char *px){ bitmap_t bmStore; bitmap_t *bitmap = &bmStore; accum->buffer=NULL; // PNG constructed in memory will end up here, caller must free(). accum->size=0; bitmap->pixels=(pixel_t *)px; bitmap->width = width; bitmap->height = height; png_structp png_ptr = NULL; png_infop info_ptr = NULL; size_t x, y; png_byte ** row_pointers = NULL; /* The following number is set by trial and error only. I cannot see where it it is documented in the libpng manual. */ int pixel_size = 3; int depth = 8; png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL){ accum->buffer=NULL; return; } info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL){ png_destroy_write_struct (&png_ptr, &info_ptr); accum->buffer=NULL; return; } /* Set up error handling. */ if (setjmp (png_jmpbuf (png_ptr))) { png_destroy_write_struct (&png_ptr, &info_ptr); accum->buffer=NULL; return; } /* Set image attributes. */ png_set_IHDR ( png_ptr, info_ptr, bitmap->width, bitmap->height, depth, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); /* Initialize rows of PNG. */ row_pointers = (png_byte **) png_malloc (png_ptr, bitmap->height * sizeof (png_byte *)); for (y = 0; y < bitmap->height; ++y) { png_byte *row = (png_byte *) png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size); row_pointers[bitmap->height - y - 1] = row; // Row order in EMF is reversed. for (x = 0; x < bitmap->width; ++x) { pixel_t * pixel = pixel_at (bitmap, x, y); *row++ = pixel->red; // R & B channels were set correctly by DIB_to_RGB *row++ = pixel->green; *row++ = pixel->blue; } } /* Write the image data to memory */ png_set_rows (png_ptr, info_ptr, row_pointers); png_set_write_fn(png_ptr, accum, my_png_write_data, NULL); png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); for (y = 0; y < bitmap->height; y++) { png_free (png_ptr, row_pointers[y]); } png_free (png_ptr, row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); }