Convert a 24-Bit Bitmap to an 8-Bit Bitmap

Source: Internet
Author: User

BMP test. h: Describes the format and structure definition of BMP files.
BMP test. cpp: converts the color data of 24bitbmp to the color data of 256 color bitmap. For more information about the algorithm, see the previous post.
BMP transfer. cpp: a program that reads a 24bitbmp file and converts it into a 256-color BMP file.

Compiled program, such as BMP transfer.exe
Run BMP transfer file1 file2
File1 is the file name of the 24bit BMP map source, and file2 is the new 256-color bitmap file name.

You can use the Windows artboard program to view the results. It seems that it is better to use the artboard program to save 24bitbmp as a 256-color BMP file.

BMP test. h

/************* BMP test. h ***************/# ifndef _ BMP test_h _ # DEFINE _ BMP test_h _ # include <stdio. h> typedef unsigned char byte; typedef unsigned short word; // descriptions of each part of the BMP image are as follows/*********** the first part of the bitmap file header is fixed in length and is 14 bytes, the fields are as follows: 2 bytes: file type, which must be 0x4d42, that is, the string "BM ". 4 Bytes: size of the entire file 4 Bytes: Reserved Words, 0 4 Bytes: the number of offset bytes from the file header to the actual bitmap image data. * ***********/Typedef struct {long imagesize; long blank; long startposition; void show (void) {printf ("BMP head: \ n "); printf (" image size: % d \ n ", imagesize); printf (" Image Data start position: % d \ n ", startposition );}} bmphead;/********************** the second part of the bitmap information header. The length of this structure is also fixed, the value is 40 bytes, and the fields are described in sequence as follows: 4 Bytes: the length of the structure, the value is 40 4 Bytes: The image width is how many pixels. 4 Bytes: the number of pixels in the Image Height. 2 byte: It must be 1. 2 byte: the number of digits used for color. The commonly used values are 1 (black and white two-color chart), 4 (16 color chart), 8 (256 color chart), and 24 (true color chart ). 4 byte: Specifies whether the bitmap is compressed. The valid values are bi_rgb, bi_rle8, bi_rle4, and bi_bitfields. Windows bitmap can be compressed in rle4 and rle8 formats. bi_rgb indicates no compression. 4 Bytes: specify the number of bytes occupied by the actual bitmap image data. The formula is as follows: image Data = width' * height * indicates the number of bytes occupied by the color of each pixel (that is, the number of digits of color/8, and the 24-bit image is 1 of 3,256 colors). Note that: in the above formula, biwidth' must be an integer multiple of 4 (not biwidth, but an integer multiple greater than or equal to the minimum 4 of biwidth ). If bicompression is bi_rgb, the value may be 0. 4 byte: horizontal resolution of the target device. 4 byte: the vertical resolution of the target device. 4 byte: number of colors actually used in the image. If the value is 0, the number of colors used is the power of 2 (number of digits of color, for example, if the number of digits of the color is 8, 2 ^ 8 = 256, that is, the bitmap of the 256 color is 4 Bytes: specify the number of important colors in the image. If the value is 0, all colors are important. * *********************************/Typedef struct {long length; long width; long height; Word colorplane; Word bitcolor; long zipformat; long realsize; long xpels; long ypels; long coloruse; long colorimportant; void show (void) {printf ("infohead length: % d \ n", length); printf ("width & Height: % d * % d \ n", width, height ); printf ("colorplane: % d \ n", colorplane); printf ("bitcolor: % d \ n", bitcolor); printf ("compr Ession format: % d \ n ", zipformat); printf (" Image Real Size: % d \ n ", realsize); printf (" pels (x, y) :( % d, % d) \ n ", xpels, ypels); printf (" coloruse: % d \ n ", coloruse); printf (" important color: % d \ n ", colorimportant) ;}} infohead; /*************************** Part 3 color palette structure for 256-color BMP bitmap, 8 digits of color, 2 ^ 8 = 256 color palette; for a 24 bitbmp bitmap, the RGB values of each pixel are directly stored in the image data area. No color palette is required, and rgbblue is not in the color palette area: the blue component of the color. Rgbgreen: the green component of the color. Rgbred: The Red weight of the color. Rgbreserved: Reserved value. * *********************/Typedef struct {byte rgbblue; byte rgbgreen; byte rgbred; byte rgbreserved; void show (void) {printf ("mix plate B, G, R: % d \ n", rgbblue, rgbgreen, rgbred) ;}} rgbmixplate; /***************************** Part 4 bitmap used in the image data area, image Data is the index value of the pixel color in the color palette. For a true color chart, image data is the actual R, G, and B values. A two-color chart uses one bit to represent the color of the pixel. Therefore, one byte can represent eight pixels. A 16-color chart uses four digits to represent the color of a pixel. Therefore, one byte can represent two pixels. A 256 color chart. one byte can represent one pixel. In a true color chart, three bytes can represent one pixel. * ************************* // Convert the 24-bit pixel color data to 256 color chart image data (index value) int transfer (word * color24bit, int Len, byte * index, rgbmixplate * maincolor); # endif

BMP test. cpp

/*************** BMP test. CPP *****************/# include "BMP test. H "# include <string. h> # include <assert. h> // calculate the squared difference function int PFC (INT color1, int color2) {int x, y, z; X = (color1 & 0xf)-(color2 & 0xf ); y = (color1> 4) & 0xf)-(color2> 4) & 0xf); Z = (color1> 8) & 0xf) -(color2> 8) & 0xf); Return (x * x + y * Y + z * z );}; // directly Insert the sorting int sort1 (int * SRC, int * attach, int N) {int cur, cur1; int I, j, k = 0; for (I = 1; I <n; I ++) {cur = SRC [I]; cur1 = attach [I]; for (j = I-1; j> = 0; j --) {If (cur> SRC [J]) {SRC [J + 1] = SRC [J]; attach [J + 1] = attach [J];} else break ;} SRC [J + 1] = cur; attach [J + 1] = cur1;} return 0;} // fast sorting int sort2 (int * SRC, int * attach, int N) {If (n <= 12) return sort1 (SRC, attach, n); int low = 1, high = n-1; int TMP; while (low <= high) {While (SRC [low]> = SRC [0]) {If (++ low> n-1) break ;} while (SRC [High] <SRC [0]) {If (-- high <1) break;} If (low> high) break; {TMP = SRC [low]; SRC [low] = SRC [High]; SRC [High] = TMP; TMP = attach [low]; attach [low] = attach [High]; attach [High] = TMP;} low ++; high -- ;}{ TMP = SRC [low-1]; SRC [low-1] = SRC [0]; SRC [0] = TMP; TMP = attach [low-1]; attach [low-1] = attach [0]; attach [0] = TMP ;} if (low> 1) sort2 (SRC, attach, low-1); If (low <n) sort2 (& SRC [low], & attach [low], n-low); Return 0;} // converts the 24-bit pixel color data to the image data of the 256 color chart (I .e. the index value) int transfer (word * color24bit, int Len, byte * index, rgbmixplate * maincolor) {int usedtimes [4096] = {0}; int minicolor [4096]; for (INT I = 0; I <4096; I ++) minicolor [I] = I; I = 0; for (I = 0; I <Len; I ++) {assert (color24bit [I] <4096 ); usedtimes [color24bit [I] ++;} int numberofcolors = 0; for (I = 0; I <4096; I ++) {If (usedtimes [I]> 0) numberofcolors ++;} // sorts usedtimes. During the sorting process, the mincolor array (storing color values) is also used to exchange sort2 (usedtimes, minicolor, 4096); // In the usedtimes array, the color usage frequency is arranged from high to low, obviously, the values after numberofcolor are 0 // the corresponding color data in the minicolor array // Save the first 256 color data to the color palette of the 256 color Bitmap (I = 0; I <256; I ++) {maincolor [I]. rgbblue = (byte) (minicolor [I]> 8) <4); maincolor [I]. rgbgreen = (byte) (minicolor [I]> 4) & 0xf) <4); maincolor [I]. rgbred = (byte) (minicolor [I] & 0xf) <4); maincolor [I]. rgbreserved = 0;} int * colorindex = usedtimes; // use the original usetimes array to save the index value memset (colorindex, 0, sizeof (INT) * 4096 ); if (numberofcolors <= 256) {for (I = 0; I <numberofcolors; I ++) colorindex [minicolor [I] = I ;} else // find the nearest {for (I = 0; I <256th; I ++) color in the first 256 colors) colorindex [minicolor [I] = I; int index, TMP, tmp1; for (I = 256; I <numberofcolors; I ++) {TMP = PFC (minicolor [0], minicolor [I]); Index = 0; For (Int J = 1; j <256; j ++) {tmp1 = PFC (minicolor [J], minicolor [I]); If (TMP> tmp1) {TMP = tmp1; Index = J ;}} colorindex [minicolor [I] = index ;}// record the index value of the color data of each point, that is, the color data of the 256 color bitmap for (I = 0; I <Len; I ++) {assert (colorindex [color24bit [I] <256); index [I] = colorindex [color24bit [I];} return 1 ;}

BMP transfer. cpp

/******************** BMP transfer. CPP ********************/# include "BMP test. H "# include <string. h> int _ cdecl main (INT argc, char * argv []) {If (argc <3) {printf ("Usage: \ n "); printf ("% s filename1 filename2 \ n", argv [0]); printf ("filename1: Source 24bit BMP filename like: xxx.bmp \ n"); printf ("filename2: new 256 color BMP filename \ n "); Return-1;} bmphead headbmp; infohead; file * P; char * Filename = argv [1]; P = fopen (filename, "rb"); If (P = NULL) {printf ("!!! File % s open failed. \ n ", filename);} printf (" file % s open success. \ n ", filename ); /*********************************/fseek (p, 2, seek_cur); fread (& headbmp, 1, 12, P); headbmp. show (); fread (& infohead, 1,40, P); infohead. show (); If (infohead. bitcolor! = 24) {fclose (p); printf ("This Is Not A 24bit BMP file. \ n "); Return-1 ;} /*********** read Image Date ***************/long ndata = infohead. realsize; byte * pcolordata = new byte [ndata]; fread (pcolordata, 1, ndata, P); printf ("last 4 bytes of color data: % x \ n ", \ pcolordata [nData-4], pcolordata [nData-3], \ pcolordata [nData-2], pcolordata [nData-1]); /*********** Read File Over ******************/INT le Ftdata = 0; char CH = 0; while (! Feof (p) {fread (& Ch, 1,1, P); leftdata ++;} If (leftdata) printf ("% d bytes not read in file. \ n ", leftdata); printf (" Read File over. \ n "); If (! Fclose (p) {printf ("file close. \ n ");} // The 24-bit BMP file information is read, you can view the print information/* 24-bit color data conversion *************** **/byte * Index = new byte [ndata/3]; rgbmixplate maincolor [256]; memset (maincolor, 0, sizeof (maincolor); word * color = new word [ndata/3]; int IRED, igreen, iblue; for (INT I = 0; I <ndata/3; I ++) {// obtain the 4-bit IRED color of the RGB color = pcolordata [I * 3]> 4; igreen = pcolordata [I * 3 + 1]> 4; iblue = pcolordata [I * 3 + 2]> 4; gradient color [I] = (IRED <8) + (igreen <4) + iblue;} Delete [] pcolordata; // call the Conversion Function transfer (partition color, ndata/3, index, maincolor); Delete [] partition color; // after the conversion is completed, the color palette data of the 256 color Bitmap (stored in maincolor) and the data in the image data area (stored in index) /*********** write a new 256-color BMP file ******************* /// modify the structure information headbmp of the previously read bmphead and infohead. imagesize = 14 + 40 + 4*256 + ndata/3; // 4*256 is the color palette length, and ndata/3 is the headbmp of the Image Data Partition length. startposition + = 4*256; // Add the color palette part infohead to the new file. bitcolor = 8; // The number of digits in the color is changed to 8 infohead. realsize = ndata/3; // image data area length // write a new file char * newfile = argv [2]; file * P1 = fopen (newfile, "WB "); if (null = p1) {printf ("open new file failed. \ n "); Return-1;} Char HH [2] = {0x42, 0x4d}; fwrite (HH, 1, 2, P1 ); // The first two bytes of the BMP file, 0x4d42 = "BM" fwrite (& headbmp, 1, 12, P1); // BMP file header fwrite (& infohead, 1, 40, p1); // BMP file header information fwrite (maincolor, 1, sizeof (maincolor), P1); // write the color palette information fwrite (index, 1, ndata/3, P1 ); // color data fclose (P1); // release the allocated memory Delete [] index; return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.