图形信息处理作业一

要求:

1.读取一个彩色 bmp 文件,把 RGB 转化为 YUV。
2. 把 Y 值调整到[0,255]范围。
3. 写出灰度 bmp 格式图像
4. 改变 Y 值,再转化为 RGB 的 bmp 图像输出

#include <stdio.h>
#include <Windows.h>


void ToRGB(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图文件头
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开位图失败\n");
		exit(-1);
	}

	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);  //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);  //读取信息头
	WORD bitCount = infoHeader.biBitCount;  //颜色位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

    int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据
	if (Clr == 0)
	{
		for (i = 0; i < pH; i++)//行
		{
			if (bitCount == 24)
			{
				for (j = 0; j < pW * 3; j = j + 3)// 列,因为每个像素占3个字节
                {
					int n = i*LineSize + j;
					int r = P[n];
					int g = P[n+1];
					int b = P[n + 2];

					int y = 0.299*r + 0.587*g + 0.114*b;
					int u = 0.492*(b - y);
					int v = 0.877*(r - y);
					y = y + 31;  //把所有像素点的y增大31
					/*if (y > 255)  //如果越界则置为255
						y = 255;
					if (y < 0)
						y = 0;
					if (u > 255)  //如果越界则置为255
						u = 255;
					if (u < 0)
						u = 0;
					if (v > 255)  //如果越界则置为255
						v = 255;
					if (v < 0)
						v = 0; */
					int R = y + 1.14*v;
					int G = y -0.394*u - 0.581*v;
					int B = y + 2.032*u;

					if (R > 255)  //R如果越界则置为255
						R = 255;
					if (R < 0)
						R = 0;
					if (G > 255)  //如果越界则置为255
						G = 255;
					if (G < 0)
						G = 0;
					if (B > 255)  //如果越界则置为255
						B = 255;
					if (B < 0)
						B = 0;
					P[n]  = (BYTE)(R); //分别是新r.g.b分量
					P[n + 1] = (BYTE)(G);
					P[n + 2] = (BYTE)(B);
				}
			}

		}
	}
	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);
	printf("处理完毕\n");
	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P=NULL;
	}
}

void ToGrey(char* a, char* b)
{
	BITMAPFILEHEADER fileHeader;// 位图头文件
	BITMAPINFOHEADER infoHeader;// 位图信息头
	FILE* pFile = fopen(a, "rb");
	if (pFile == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}
	// 读取头信息
	fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);   //读取文件头
	fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);   //读取信息头
	WORD bitCount = infoHeader.biBitCount;//色彩的位数
	if (bitCount == 16)
	{
		exit(-1);
	}
	int Clr = 0;

	RGBQUAD *QUAD = NULL;
	if (bitCount < 16)
	{

		Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount;
		if (Clr>256)
			Clr = 0;
	}
	// 读取调色板
	int i = 0, j = 0;
	if (Clr > 0)
	{
		QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr);
		fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile);
		for (i = 0; i < Clr; i++)
		{
			QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen =
				(BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue);  //灰度图像三个都是y
		}
	}
	LONG pW = infoHeader.biWidth;     //图像数据的宽度
	LONG pH = infoHeader.biHeight;    //图像数据的高度

	int pSize = ((pW * bitCount)>>3)*pH;  //图像数据大小
	BYTE* P = (BYTE*)malloc(pSize);   //申请空间保存图像数据
	int LineSize = ((pW * bitCount)>> 3);  //行数据大小
	fread(P, pSize, 1, pFile);     //存入图像数据
	if (Clr == 0)
	{
		for (i = 0; i < pH; i++)//行
		{
			if (bitCount == 24)
			{
				for (j = 0; j < pW*3; j = j + 3)// 列
				{
					int n = i*LineSize + j;
					P[n] = P[n + 1] = P[n + 2] = (BYTE)(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]); //分别是r,g,b分量

				}printf("处理完毕");
			}

		}
	}

	FILE* dFile = fopen(b, "wb");//创建目标文件

	fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile);   //写入文件头

	fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile);  //写入文件信息头
	if (QUAD)
	{
		fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile);
	}
	//写入图像数据
	fwrite(P, pSize, 1, dFile);
	fclose(dFile);
    printf("处理完毕\n");
	if (QUAD)
	{
		free(QUAD);
		QUAD = NULL;
	}
	if (P)
	{
		free(P);
		P = NULL;
	}
}

int main()
{
	ToGrey("a.bmp", "graya.bmp");
	ToRGB("a.bmp", "rgba.bmp");
    ToGrey("b.bmp", "grayb.bmp");
	ToRGB("b.bmp", "rgbb.bmp");
	ToGrey("c.bmp", "grayc.bmp");
	ToRGB("c.bmp", "rgbc.bmp");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水木流年追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值