Reading a template from a file and creating a BMP image in C

I want to read a text file using the C Language.Here file: -

enter image description here

You see that there is a template in the text content of the file. 0 means nothing. 9 means black. therefore there is a coloring scheme from 0 to 9.

I need to create a bitmap of this, and the color matches the values ​​in the template. You must configure it using the 0-256 color scheme. And the final conclusion for this is shown below.

enter image description here

Now see that the template in the contents of the text file matches the final output raster file (optional). The darkness of the colors in the bitmap corresponds to the values ​​in the text content template.

Someone tell me how I do it in C.

I can create a BMP file, but not according to the pattern in the text file.

#include <stdio.h> #include <stdlib.h> int main() { char bitmap[1900]; // -- FILE HEADER -- // // bitmap signature bitmap[0] = 0x42; bitmap[1] = 0x4d; // file size bitmap[2] = 58; // 40 + 14 + 12 bitmap[3] = 0; bitmap[4] = 0; bitmap[5] = 0; int i=0; // reserved field (in hex. 00 00 00 00) for(i = 6; i < 10; i++) bitmap[i] = 0; // offset of pixel data inside the image for(i = 10; i < 14; i++) bitmap[i] = 0; // -- BITMAP HEADER -- // // header size bitmap[14] = 40; for(i = 15; i < 18; i++) bitmap[i] = 0; // width of the image bitmap[18] = 4; for(i = 19; i < 22; i++) bitmap[i] = 0; // height of the image bitmap[22] = 1; for(i = 23; i < 26; i++) bitmap[i] = 0; // reserved field bitmap[26] = 1; bitmap[27] = 0; // number of bits per pixel bitmap[28] = 24; // 3 byte bitmap[29] = 0; // compression method (no compression here) for(i = 30; i < 34; i++) bitmap[i] = 0; // size of pixel data bitmap[34] = 12; // 12 bits => 4 pixels bitmap[35] = 0; bitmap[36] = 0; bitmap[37] = 0; // horizontal resolution of the image - pixels per meter (2835) bitmap[38] = 0; bitmap[39] = 0; bitmap[40] = 0b00110000; bitmap[41] = 0b10110001; // vertical resolution of the image - pixels per meter (2835) bitmap[42] = 0; bitmap[43] = 0; bitmap[44] = 0b00110000; bitmap[45] = 0b10110001; // color pallette information for(i = 46; i < 50; i++) bitmap[i] = 0; // number of important colors for(i = 50; i < 54; i++) bitmap[i] = 0; // -- PIXEL DATA -- // for(i = 54; i < 66; i++) bitmap[i] = 255; FILE *file; file = fopen("bitmap.bmp", "w+"); for(i = 0; i < 66; i++) { fputc(bitmap[i], file); } fclose(file); return 0; } 
+5
source share
2 answers

Here is the working code. I do not check for any case of error (for example, the input file is poorly formatted). I added some comments, although the code itself is not hard to understand.

 #include <stdlib.h> #include <stdint.h> #include <assert.h> #include <string.h> #include <stdio.h> #include <stdbool.h> #include <errno.h> #include <ctype.h> #define BMP_ASSERT(condition, message) \ do { \ if (! (condition)) { \ fprintf(stderr, __FILE__ ":%d: %s: Assertion `" #condition \ "` failed.\n\t: %s\n", __LINE__, __func__, message); \ exit(EXIT_FAILURE); \ } \ } while (false) #define BMP_COLORMAP_SIZE 10 //////////////////////////////////////////////////////////////////////////////// // STRUCTS typedef struct __attribute__((__packed__)) bmp_color { uint8_t r, g, b; uint8_t :8; } bmp_color_t; typedef struct __attribute__((__packed__)) bmp_header_infos { uint32_t const info_size; uint32_t width; uint32_t height; uint16_t const planes; uint16_t const bpp; uint32_t const compression; uint32_t img_size; uint32_t const horz_resolution; uint32_t const vert_resolution; uint32_t const n_colors; uint32_t const n_important_colors; } bmp_header_infos_t; typedef struct __attribute__((__packed__)) bmp_header { /* Header */ char const signature[2]; uint32_t file_size; uint32_t const :32; // reserved uint32_t const img_offset; /* Infos */ bmp_header_infos_t infos; /* Color map */ bmp_color_t colormap[BMP_COLORMAP_SIZE]; } bmp_header_t; typedef struct bmp_file_datas { size_t width; size_t height; /* Bit map */ uint8_t *bitmap; } bmp_file_datas_t; //////////////////////////////////////////////////////////////////////////////// // FUNCTIONS /* Give a header with the right magic values */ bmp_header_t * bmp_get_header(void) { static bmp_header_t _header = { {'B', 'M'}, 0u, sizeof(_header), { // struct info sizeof(_header.infos), 0u, 0u, // width, height 1u, // planes 8u, // bpp 0u, // no compression 0u, // img size 0u, 0u, // resolution BMP_COLORMAP_SIZE, BMP_COLORMAP_SIZE, // important colors }, {{0u}} }; bmp_header_t *header = malloc(sizeof(_header)); size_t i, color; assert(header != NULL); memcpy(header, &_header, sizeof(*header)); // setting the scale of greys for (i = 0 ; i < BMP_COLORMAP_SIZE ; ++i) { color = (i * 255) / BMP_COLORMAP_SIZE; header->colormap[i] = (bmp_color_t){color, color, color}; } return header; } /* Take all the file content and store it in a buffer */ char * get_file_content(char const *filename) { FILE *file_handler = fopen(filename, "r"); size_t file_len; char *buff; BMP_ASSERT(file_handler != NULL, strerror(errno)); fseek(file_handler, 0, SEEK_END); file_len = ftell(file_handler); fseek(file_handler, 0, SEEK_SET); buff = malloc(file_len + 1); assert(buff != NULL); fread(buff, file_len, 1, file_handler); buff[file_len] = '\0'; fclose(file_handler); return buff; } /* Get the greatest multiple of 4 that is >= size */ static inline size_t multiple_of_four(size_t size) { while (size % 4) ++size; return size; } /* Get the informations from buffer: size of line, number of lines */ void get_file_infos(char *buff, bmp_header_t *header, bmp_file_datas_t *datas) { /* width & height */ header->infos.width = strchr(buff, '\n') - buff; header->infos.height = strlen(buff) / (header->infos.width + 1); // + 1 for the terminating '\n' datas->width = multiple_of_four(header->infos.width); datas->height = header->infos.height; printf("File size: %u, %u\n", header->infos.width, header->infos.height); /* image size & bitmap allocation */ header->infos.img_size = datas->width * datas->height; datas->bitmap = malloc(header->infos.img_size * sizeof(*datas->bitmap)); assert(datas->bitmap != NULL); header->file_size = header->img_offset + header->infos.img_size; } /* Take the informations from the buffer and store them in the bitmap */ void write_bitmap(char *buff, bmp_file_datas_t *datas) { size_t ibuff, iline = 0, ibitmap = 0; for (ibuff = 0 ; buff[ibuff] ; ++ibuff) { if (isdigit(buff[ibuff])) { datas->bitmap[ibitmap] = BMP_COLORMAP_SIZE - 1 - (buff[ibuff] - '0'); ++ibitmap; } else if (buff[ibuff] == '\n') { ++iline; ibitmap = iline * datas->width; } } } /* Write the datas in the file: the header and the bitmap */ void write_in_file(bmp_header_t *header, bmp_file_datas_t *datas, char const *filename) { FILE *file_handler = fopen(filename, "w"); BMP_ASSERT(file_handler != NULL, strerror(errno)); fwrite(header, sizeof(*header), 1, file_handler); fwrite(datas->bitmap, header->infos.img_size, 1, file_handler); fclose(file_handler); } int main(int argc, char **argv) { char *buff; bmp_header_t *header; bmp_file_datas_t datas; if (argc != 3) { fprintf(stderr, "Usage: %s <input filename> <output filename>\n", argv[0]); return EXIT_FAILURE; } buff = get_file_content(argv[1]); header = bmp_get_header(); get_file_infos(buff, header, &datas); write_bitmap(buff, &datas); write_in_file(header, &datas, argv[2]); free(buff), free(header), free(datas.bitmap); return EXIT_SUCCESS; } 
+4
source

A rough method to achieve the required functionality would be: (Not really C, but then this is your homework not mine)

 WIDTH = 0, HEIGHT = 0 if(LINE=READ_LINE(fin)) WIDTH = strlen(LINE) ++HEIGHT else ERROR!!! PUSH(LINE) while(LINE=READ_LINE(fin)) if(WIDTH != strlen(LINE)) ERROR!!! else ++HEIGHT PUSH(LINE) WRITE_BMP_HEADER(WIDTH, HEIGHT) for(h = 0; h < HEIGHT; ++h) LINE = POP() for(w = 0; w < WIDTH; ++w) COLOR = (LINE[w] - '0') * 255 / 9; WRITE_BMP_COLOR(COLOR) WRITE_BMP_PADDING(W) 
+2
source

All Articles