BMP圖24位轉換成1位單色

昨天在工作的時候又遇到了這個問題 所以在此記錄一下 這是個純c語言的 兼容性不錯 

24位BMP轉1位BMP  

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);

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章