The C language converts the color BMP bitmap into a Binary Map, bmp bitmap
CTF does not have a systematic understanding of the hidden Question of the image. First, we will summarize the composition of the BMP image and deepen our understanding by converting the color image into a binary image.
Only the format and code implementation of Bitmap binary files are written. Some concepts such as RGB color and color palette are not too long.
BMP bitmap file format
A bmp file consists of four parts: File Header, bitmap information header, color palette, and graphic data. A true color chart has no color palette. The specific structure of each part is listed and explained in the code.
Structure alignment
Definition file header structure should pay attention to the problem of alignment, as to what is the structure alignment, please read this blog, write a very detailed http://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html
Four-byte bitmap alignment
This alignment is the alignment of the pixels in each row of the bitmap. Do not confuse it with the alignment of the above structure. The number of pixels in each row must be an integer multiple of 4 bytes, and fill in insufficient pixels, at this time, because the memory allocation unit is 32 bits, that is, 4 bytes, each row of read pixels is continuous and cannot occupy one memory unit with other rows.
Convert a color image to a grayscale image
RGB has a total of 256 gray components, that is, the color of R = G = B is gray, so it can be expressed in one byte, to convert a color image to a grayscale image is to make the three color components of a true color image equal to the same value. The exact value can be the same as that of multiple methods, such as obtaining the average value of the three components, take the maximum value of three components or make two of them equal to the value of another component. Another common method is to take the weighted average value, according to this well-known psychology formula Gray = R * 0.299 + G * 0.587 + B * 0.114
Converting a grayscale image to a Binary Graph
A two-value diagram has only two colors: black and white, while a gray scale has 256 colors. to convert a gray scale to a two-value diagram, you can select a threshold and set the gray scale value greater than this threshold value to white, black is the opposite. There are also many ways to select the threshold value and the scope of its function. I will not repeat it here. To make it simple, I will select a fixed threshold value of 190 globally (for my test image, I typed 190 by hand, and the conversion effect is acceptable. The Binary Graph only has two indexes, which can be expressed in 1 bit, but the program I wrote is represented in 1 byte, as for how to compress, it's up to you...
After talking about this, let's look at the code. This makes it easier to understand. I seem to have written a Comment comment into every line.
1 /*
2 Author: Azure Line
3 Blog: http://www.cnblogs.com/duanv/
4 * /
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 / * Bitmap file header * /
9 #pragma pack (1) // Single byte alignment
10 typedef struct tagBITMAPFILEHEADER
11 {
12 unsigned char bfType [2]; // File format
13 unsigned int bfSize; // file size
14 unsigned short bfReserved1; // Reserved
15 unsigned short bfReserved2; // Reserved
16 unsigned int bfOffBits; // data offset
17} fileHeader;
18 #pragma pack ()
19
20 / * Bitmap information header * /
21 #pragma pack (1)
22 typedef struct tagBITMAPINFOHEADER
twenty three {
24 unsigned int biSize; // Number of words required by the BITMAPINFOHEADER structure
25 int biWidth; // Image width in pixels
26 int biHeight; // The image height, in pixels, is a positive number, the image is in reverse order, the image is negative, and the image is positive order
27 unsigned short biPlanes; // Specify the number of color planes for the target device, always set to 1
28 unsigned short biBitCount; // Describes the number of bits / pixel
29 unsigned int biCompression; // Describe the type of data compression
30 unsigned int biSizeImage; // Describe the image size, in bytes
31 int biXPixPerMeter; // Horizontal resolution, pixels / meter
32 int biYPixPerMeter; // vertical resolution
33 unsigned int biClrUsed; // Number of color indexes
34 unsigned int biClrImportant; // The number of important color indexes, 0 means that it is important
35} fileInfo;
36 #pragma pack ()
37
38 / * palette structure * /
39 #pragma pack (1)
40 typedef struct tagRGBQUAD
41 {
42 unsigned char rgbBlue; // Blue sub-brightness
43 unsigned char rgbGreen; // Green sub-brightness
44 unsigned char rgbRed; // Red sub-brightness
45 unsigned char rgbReserved;
46} rgbq;
47 #pragma pack ()
48
49 int main ()
50 {
51 / * variable declaration * /
52 FILE * fpBMP, * fpTwoValue; // source file fpBMP, target file fpTwoValue
53
54 fileHeader * fh; // Bitmap file header
55 fileInfo * fi; // bitmap information header
56 rgbq * rg; // palette
57
58 int i, j, k = 0;
59 unsigned char * a; // Store the pixel value of each line of the source image
60 unsigned char b; // store the gray value or binary value of each pixel
61 unsigned char * c; // store the binary value of each row of pixels
62
63 / ************************************************ ******************** /
64
65 / * Open source file and create output file * /
66 if ((fpBMP = fopen ("/ Users / SPY / Desktop / 1.bmp", "rb")) == NULL) {
67 printf ("file open failed");
68 exit (0);
69}
70
71 if ((fpTwoValue = fopen ("/ Users / SPY / Desktop / 2.bmp", "wb")) == NULL) {
72 printf ("file creat failed");
73 exit (0);
74}
75
76 / ************************************************ ******************** /
77
78 / * Create bitmap file header, information header, palette * /
79 fh = (fileHeader *) malloc (sizeof (fileHeader));
80 fi = (fileInfo *) malloc (sizeof (fileInfo));
81 rg = (rgbq *) malloc (2 * sizeof (rgbq));
82
83 / * Read source bitmap file header and information header * /
84 fread (fh, sizeof (fileHeader), 1, fpBMP);
85 fread (fi, sizeof (fileInfo), 1, fpBMP);
86
87 / * Modify file header, header information * /
88 fi-> biBitCount = 8; // After converting to a binary image, the color depth changed from 24 bits to 8 bits
89 fi-> biSizeImage = ((fi-> biWidth + 3) / 4) * 4 * fi-> biHeight; // Each pixel changes from three bytes to a single byte, and each row of pixels needs to be four-byte aligned
90 fi-> biClrUsed = 2; // Number of color index tables, binary map is 2
91 fi-> biClrImportant = 0; // important color index is 0, indicating that all are important
92 fh-> bfOffBits = sizeof (fileHeader) + sizeof (fileInfo) + 2 * sizeof (rgbq); // The data area offset is equal to the sum of the size of the file header, information header, and index table
93 fh-> bfSize = fh-> bfOffBits + fi-> biSizeImage; // File size, which is equal to the offset plus the size of the data area
94 rg [0] .rgbBlue = rg [0] .rgbGreen = rg [0] .rgbRed = rg [0] .rgbReserved = 0; // The palette color is black and the corresponding index is 0
95 rg [1] .rgbBlue = rg [1] .rgbGreen = rg [1] .rgbRed = 255; // The corresponding index for white is 1
96 rg [1] .rgbReserved = 0;
97
98 / ************************************************ ******************** /
99
100 / * Write bitmap file header, information header and palette to file * /
101 fwrite (fh, sizeof (fileHeader), 1, fpTwoValue);
102 fwrite (fi, sizeof (fileInfo), 1, fpTwoValue);
103 fwrite (rg, 2 * sizeof (rgbq), 1, fpTwoValue);
104
105 / * Convert color map to binary map * /
106 a = (unsigned char *) malloc ((fi-> biWidth * 3 + 3) / 4 * 4); // Apply to variable a for the space occupied by the pixels of each row of the source image.
107 c = (unsigned char *) malloc ((fi-> biWidth + 3) / 4 * 4); // Apply to variable c for the space occupied by the pixels of each row of the target image, the same four bytes
108
109 for (i = 0; i <fi-> biHeight; i ++) {// loop through each line of the image
110 for (j = 0; j <((fi-> biWidth * 3 + 3) / 4 * 4); j ++) {// loop through each byte in each line
111 fread (a + j, 1,1, fpBMP); // Read each byte of each line of the source image into the memory space pointed to by variable a
112 // printf ("% d", a [j]);
113}
114 for (j = 0; j <fi-> biWidth; j ++) {/ Cycle pixel width times, it will not calculate read four-byte padding bits
115 b = (int) (0.114 * (float) a [k] + 0.587 * (float) a [k + 1] + 0.299 * (float) a [k + 2]); // every three words The sections represent the BGR components, and are multiplied by different weights to convert to gray values.
116 // printf ("% d", b);
117 if (190 <= (int) b) b = 1; // The gray value is converted into a binary value, and the threshold value selected here is 190
118 else b = 0;
119 c [j] = b; // store the binary value of each line
120 k + = 3;
121}
122 fwrite (c, (fi-> biWidth + 3) / 4 * 4,1, fpTwoValue); // Four-byte pixel four-byte padding is written to the file.
123 k = 0;
124}
125
126 / ************************************************ ******************** /
127
128 / * Free up memory space and close files * /
129 free (fh);
130 free (fi);
131 free (rg);
132 free (a);
133 free (c);
134 fclose (fpBMP);
135 fclose (fpTwoValue);
136 printf ("success! \ N");
137 return 0;
138}
The running result is as follows (Bitmap upload is not supported. You can only view the result ):