昨天在工做的時候又遇到了這個問題 因此在此記錄一下 這是個純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); }