昨天在工做的时候又遇到了这个问题 因此在此记录一下 这是个纯c语言的 兼容性不错 算法
24位BMP转1位BMP api
FILE* SetRGBQUAD(FILE *wfile) { int i; RGBQUAD rgbquad[2]; for (i = 0; i<2; i++) { rgbquad[i].rgbBlue = i ? 0xFF : 0; rgbquad[i].rgbGreen = i ? 0xFF : 0; rgbquad[i].rgbRed = i ? 0xFF : 0; rgbquad[i].rgbReserved = 0; } fwrite(rgbquad, 2 * sizeof(RGBQUAD), 1, wfile); return wfile; } void bit24_to_uv1() { FILE *opfile; int m; int space_byte = 0; unsigned char spacestr[5]; WORD bfType; if ((opfile = fopen("c:\\CardTEMP\\Kr_temp.bmp", "rb")) == NULL)//原图地址 24位 { #ifdef TRACE_ON SPTRACE(L"ZB: Kr File can not open! - (%d line)", __LINE__); #endif return; } FILE *wrfile; if ((wrfile = fopen("c:\\CardTEMP\\Kr_Front.bmp", "wb")) == NULL)//转化的图片 1位 { #ifdef TRACE_ON SPTRACE(L"ZB: Kr wrfile can not open! - (%d line)", __LINE__); #endif return; } //先读取文件类型 //fread(&bfType, 1, sizeof(WORD), opfile); BITMAPFILEHEADER fileHead; fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, opfile); BITMAPINFOHEADER bitmapinfoHead; fread(&bitmapinfoHead, sizeof(BITMAPINFOHEADER), 1, opfile); unsigned char rgb[3]; unsigned int pitchcount; unsigned char r, g, b; unsigned char gray; unsigned char writein = 0; int k; bitmapinfoHead.biBitCount = 1; bitmapinfoHead.biClrUsed = 0; fileHead.bfOffBits = 54 + 2 * sizeof(RGBQUAD); bitmapinfoHead.biSizeImage = ((((bitmapinfoHead.biWidth*bitmapinfoHead.biBitCount) + 31)&~31) / 8)*bitmapinfoHead.biHeight; fileHead.bfSize = fileHead.bfOffBits + bitmapinfoHead.biSizeImage; //fwrite(&bfType, 1, sizeof(WORD), wrfile); fwrite(&fileHead, sizeof(BITMAPFILEHEADER), 1, wrfile); fwrite(&bitmapinfoHead, sizeof(BITMAPINFOHEADER), 1, wrfile); wrfile = SetRGBQUAD(wrfile); //fwrite(&bitmapinfoHead, sizeof(BITMAPINFOHEADER), 1, wrfile); //fseek(opfile,fileHead.bfOffBits,0); for (int i = 0; i < bitmapinfoHead.biHeight; i++) { writein = 0; pitchcount = 0; k = 0; space_byte = 0; for (int j = 0; j < bitmapinfoHead.biWidth; j++) { fread(&rgb, 3, 1, opfile); if (feof(opfile)) { break; } // rgb: 0x00bbggrr b = rgb[2]; g = rgb[1]; r = rgb[0]; gray = (unsigned char)((r + g + b) / 3); // 24位转8位核心算法 if (gray >= 128) //白点 { writein |= 1; } ++k; if (k == 8) { pitchcount++; // 有效行数据字节总数+1 fwrite(&writein, 1, 1, wrfile); writein = 0; k = 0; } writein <<= 1; //右移1位 } if (k != 0) //不足一个字节用0填充剩余位 { writein <<= (8 - k); fwrite(&writein, 1, 1, wrfile); pitchcount++; } if (pitchcount % 4 != 0) //4字节对齐 { writein = 0; for (m = 0; m < 4 - pitchcount % 4; m++) { fwrite(&writein, sizeof(char), 1, wrfile); } } if (bitmapinfoHead.biWidth % 4 != 0) { space_byte = 4 - (bitmapinfoHead.biWidth % 4); fread(&spacestr, space_byte, 1, opfile); } } fclose(opfile); fclose(wrfile); }