c语言实现真彩图到灰度图的转化

最近正在学习数字图像处理,研究了bmp图像的相关知识,下面是用c语言实现的将真彩图转化为灰度图。可能写的比较乱,但运行结果还是正确的。

程序区分了灰度图与真彩图,如果打开的文件1本身是灰度图,则直接文件存储在2中,若文件1是真彩图,则转化为灰度图后存在2中

#include "stdafx.h"
#include<stdio.h>
#include<windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
	int bmpHeight;
	int bmpWidth;
	unsigned char *pBmpBuf;
	RGBQUAD *pColorTable;
	int biBitCount;

	//读取bmp文件
	FILE *fp=fopen("dog1.bmp","rb");
	if(fp==0)
		return 0;
	fseek(fp,sizeof(BITMAPFILEHEADER),0);

	BITMAPINFOHEADER head;
	fread(&head,40,1,fp);
	bmpHeight=head.biHeight;
	bmpWidth=head.biWidth;
	biBitCount=head.biBitCount;
	
	if(biBitCount==8)
	{
		pColorTable=new RGBQUAD[256];
		fread(pColorTable,sizeof(RGBQUAD),256,fp);
	}
	int LineByte=(bmpWidth*biBitCount/8+3)/4*4;//保证每一行字节数都为4的整数倍
	pBmpBuf=new unsigned char[LineByte*bmpHeight];
	fread(pBmpBuf,LineByte*bmpHeight,1,fp);
	fclose(fp);
	测试读取功能模块
	printf("bmpWidth:%d ,bmpHeight: %d,biBitCount:%d \n",bmpWidth,bmpHeight,biBitCount);

	//将24位真彩图灰度化并保存

	FILE *fp1=fopen("dog2.bmp","wb");
	if(fp1==0)
		return 0;
	int LineByte1=(bmpWidth*8/8+3)/4*4;
	//修改文件头,其中有两项需要修改,分别为bfSize和bfOffBits
	BITMAPFILEHEADER bfhead;
	bfhead.bfType=0x4D42;
	bfhead.bfSize=14+40+256*sizeof(RGBQUAD)+LineByte1*bmpHeight;//修改文件大小
	bfhead.bfReserved1=0;
	bfhead.bfReserved2=0;
	bfhead.bfOffBits=14+40+256*sizeof(RGBQUAD);//修改偏移字节数
	fwrite(&bfhead,14,1,fp1);    //将修改后的文件头存入fp1;

	//修改信息头,其中有两项需要修改,1个位biBitCount:真彩图为24 ,应改成8;另一个是biSizeImage:由于每像素所占位数的变化,所以位图数据的大小发生变化
	BITMAPINFOHEADER head1;
	head1.biBitCount=8;    //将每像素的位数改为8
	head1.biClrImportant=0;
	head1.biCompression=0;
	head1.biClrUsed=0;
	head1.biHeight=bmpHeight;
	head1.biWidth=bmpWidth;
	head1.biPlanes=1;
	head1.biSize=40;
	head1.biSizeImage=LineByte1*bmpHeight;//修改位图数据的大小
	head1.biXPelsPerMeter=0;
	head1.biYPelsPerMeter=0;
	fwrite(&head1,40,1,fp1);  //将修改后的信息头存入fp1;

	if(biBitCount==24)//判断是否是真彩图,若是,由于真彩图没有颜色表,所以在变为灰度图后要加上颜色表
	{
		pColorTable=new RGBQUAD[256];
 		for (int  i = 0; i < 256; i++ )
			pColorTable[i].rgbRed = pColorTable[i].rgbGreen = pColorTable[i].rgbBlue = i; //是颜色表里的B、G、R分量都相等,且等于索引值

	}
	fwrite(pColorTable,sizeof(RGBQUAD),256,fp1); //将颜色表写入fp1;

	//写位图数据
	unsigned char *pBmpBuf1;
	pBmpBuf1= new unsigned char[LineByte1*bmpHeight];
	for(int i=0;i<bmpHeight;i++)
		for(int j=0;j<bmpWidth;j++)
		{
			unsigned char *pb1,*pb2;
			pb1=pBmpBuf+i*LineByte+j*3;
			int y=*(pb1)*0.299+*(pb1+1)*0.587+*(pb1+2)*0.114;   //将每一个像素都按公式y=B*0.299+G*0.587+R*0.114进行转化
			pb2=pBmpBuf1+i*LineByte1+j;
			*pb2=y;

		}
	if(biBitCount==8)
		fwrite(pBmpBuf,LineByte*bmpHeight,1,fp1);
	else
		fwrite(pBmpBuf1,LineByte1*bmpHeight,1,fp1);


	fclose(fp1);

	system("pause");
	return 0;
}

    

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值