Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.05 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<string.h>
  3. typedef struct rgb_data {
  4. float r, g, b;
  5. }RGB;
  6.  
  7.  
  8. void save_bitmap(const char *file_name, int width, int height, int dpi, RGB *pixel_data)
  9. {
  10. // create a file object that we will use to write our image
  11. FILE *image;
  12. // we want to know how many pixels to reserve
  13. int image_size = width * height;
  14. // a byte is 4 bits but we are creating a 24 bit image so we can represent a pixel with 3
  15. // our final file size of our image is the width * height * 4 + size of bitmap header
  16. int file_size = 54 + 4 * image_size;
  17. // pixels per meter https://www.wikiwand.com/en/Dots_per_inch
  18. int ppm = dpi * 39.375;
  19.  
  20. // bitmap file header (14 bytes)
  21. // we could be savages and just create 2 array but since this is for learning lets
  22. // use structs so it can be parsed by someone without having to refer to the spec
  23.  
  24. // since we have a non-natural set of bytes, we must explicitly tell the
  25. // compiler to not pad anything, on gcc the attribute alone doesn't work so
  26. // a nifty trick is if we declare the smallest data type last the compiler
  27. // *might* ignore padding, in some cases we can use a pragma or gcc's
  28. // __attribute__((__packed__)) when declaring the struct
  29. // we do this so we can have an accurate sizeof() which should be 14, however
  30. // this won't work here since we need to order the bytes as they are written
  31. struct bitmap_file_header {
  32. unsigned char bitmap_type[2]; // 2 bytes
  33. int file_size; // 4 bytes
  34. short reserved1; // 2 bytes
  35. short reserved2; // 2 bytes
  36. unsigned int offset_bits; // 4 bytes
  37. } bfh;
  38.  
  39. // bitmap image header (40 bytes)
  40. struct bitmap_image_header {
  41. unsigned int size_header; // 4 bytes
  42. unsigned int width; // 4 bytes
  43. unsigned int height; // 4 bytes
  44. short int planes; // 2 bytes
  45. short int bit_count; // 2 bytes
  46. unsigned int compression; // 4 bytes
  47. unsigned int image_size; // 4 bytes
  48. unsigned int ppm_x; // 4 bytes
  49. unsigned int ppm_y; // 4 bytes
  50. unsigned int clr_used; // 4 bytes
  51. unsigned int clr_important; // 4 bytes
  52. } bih;
  53.  
  54. // if you are on Windows you can include <windows.h>
  55. // and make use of the BITMAPFILEHEADER and BITMAPINFOHEADER structs
  56.  
  57. memcpy(&bfh.bitmap_type, "BM", 2);
  58. bfh.file_size = file_size;
  59. bfh.reserved1 = 0;
  60. bfh.reserved2 = 0;
  61. bfh.offset_bits = 0;
  62.  
  63. bih.size_header = sizeof(bih);
  64. bih.width = width;
  65. bih.height = height;
  66. bih.planes = 1;
  67. bih.bit_count = 24;
  68. bih.compression = 0;
  69. bih.image_size = file_size;
  70. bih.ppm_x = ppm;
  71. bih.ppm_y = ppm;
  72. bih.clr_used = 0;
  73. bih.clr_important = 0;
  74.  
  75. image = fopen(file_name, "wb");
  76.  
  77. // compiler woes so we will just use the constant 14 we know we have
  78. fwrite(&bfh, 1, 14, image);
  79. fwrite(&bih, 1, sizeof(bih), image);
  80.  
  81. // write out pixel data, one last important this to know is the ordering is backwards
  82. // we have to go BGR as opposed to RGB
  83. for (int i = 0; i < image_size; i++) {
  84. RGB BGR = pixel_data[i];
  85.  
  86. float red = (BGR.r);
  87. float green = (BGR.g);
  88. float blue = (BGR.b);
  89.  
  90. // if you don't follow BGR image will be flipped!
  91. unsigned char color[3] = {
  92. blue, green, red
  93. };
  94.  
  95. fwrite(color, 1, sizeof(color), image);
  96. }
  97.  
  98. fclose(image);
  99. }
  100.  
  101. int main()
  102. {
  103. const int width = 400, height = 400, dpi = 96;
  104.  
  105. RGB pixels[width * height];
  106.  
  107.  
  108. for (int x = 0; x < width; x++)
  109. {
  110. for (int y = 0; y < height; y++)
  111. {
  112. int a = y * width + x;
  113.  
  114. if ((x > 50 && x < 350) && (y > 50 && y < 350))
  115. {
  116. pixels[a].r = 255;
  117. pixels[a].g = 255;
  118. pixels[a].b = 5;
  119. } else {
  120. pixels[a].r = 55;
  121. pixels[a].g = 55;
  122. pixels[a].b = 55;
  123. }
  124. }
  125. }
  126.  
  127. save_bitmap("black_border.bmp", width, height, dpi, pixels);
  128.  
  129. system("black_border.bmp");
  130.  
  131. return 0;
  132.  
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement