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

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值