BMP转换YUV实验

BMP文件解析

BMP文件主要有四部分组成,位图头、位图信息、调色板、位图数据。

位图头
保存文件的总体信息

字节 #0-1 保存位图文件的标识符,用于标识BMP和DIB文件的魔数,一般为0x42 0x4D,即ASCII的BM。以下为可能的取值:
BM – Windows 3.1x, 95, NT, … etc.
BA – OS/2 struct Bitmap Array
CI – OS/2 struct Color Icon
CP – OS/2 const Color Pointer
IC – OS/2 struct Icon
PT – OS/2 Pointer
字节 #2-5 使用一个dword保存位图文件大小。
字节 #6-9 是保留部分,留做以后的扩展使用,对实际的解码格式没有影响。
字节 #10-13 保存位图数据位置的地址偏移,也就是起始地址。
位图信息
这部分告诉应用程序图像的详细信息,在屏幕上显示图像将会使用这些信息

字节 #14-17 定义以下用来描述影像的区块(BitmapInfoHeader)的大小。
字节 #18-21 保存位图宽度(以像素个数表示)。
字节 #22-25 保存位图高度(以像素个数表示)。
字节 #26-27 保存所用彩色位面的个数。不经常使用。
字节 #28-29 保存每个像素的位数,它是图像的颜色深度。常用值是1、4、8(灰阶)和24(彩色)。
字节 #30-33 定义所用的压缩算法。允许的值是0、1、2、3、4、5。
0 - 没有压缩(也用BI_RGB表示)
1 - 行程长度编码 8位/像素(也用BI_RLE8表示)
2 - 行程长度编码4位/像素(也用BI_RLE4表示)
3 - Bit field(也用BI_BITFIELDS表示)
4 - JPEG图像(也用BI_JPEG表示)
5 - PNG图像(也用BI_PNG表示)
调色板
暂时不做介绍

位图数据
在典型的24位位图下,一个像素由24bit,即3个字节(R\G\B)组成。

程序实现


#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include<windows.h>
#include"bmp2yuv.h"

BITMAPFILEHEADER File_header; 
BITMAPINFOHEADER Info_header;


	if(fread(&File_header,sizeof(BITMAPFILEHEADER),1,bmpFile)!=1)
	{
		printf("read file header error!\n");
		exit(0);
	}
	if(File_header.bfType!=0x4D42)
	{
		printf("Not bmp file!\n");
		exit(0);
	}
	else
	{
		printf("This is a bmp file!\n");
	}
		if(fread(&Info_header,sizeof(BITMAPINFOHEADER),1,bmpFile)!=1)
	{
		printf("read info header error!\n");
		exit(0);
	}

	frameWidth = Info_header.biWidth;
	frameHeight = Info_header.biHeight;


		
		bmpBuf = (unsigned char*)malloc(frameWidth * frameHeight * 4);
		
		yBuf = (unsigned char*)malloc(frameWidth * frameHeight);
		uBuf = (unsigned char*)malloc((frameWidth * frameHeight) / 4);
		vBuf = (unsigned char*)malloc((frameWidth * frameHeight) / 4);
		if (bmpBuf == NULL || yBuf == NULL || uBuf == NULL || vBuf == NULL)
		{
			printf("no enought memory\n");
			exit(1);
		}

		if(fread(bmpBuf, 1, frameWidth * frameHeight * 4, bmpFile)==NULL)
		{
			printf("read data error!\n");
			exit(1);
		}
		
for (int i = 0; i < frameWidth*frameHeight; i++)
		{
			if (yBuf[i] < 16) yBuf[i] = 16;
			if (yBuf[i] > 235) yBuf[i] = 235;
		}

		for (int i = 0; i < frameWidth*frameHeight/4; i++)
		{
			if (uBuf[i] < 16) uBuf[i] = 16;
			if (uBuf[i] > 240) uBuf[i] = 240;

			if (vBuf[i] < 16) vBuf[i] = 16;
			if (vBuf[i] > 240) vBuf[i] = 240;
		}

for (int i = 0; i < 40; i++)
		{
			fwrite(yBuf, 1, frameWidth * frameHeight, yuvFile);
			fwrite(uBuf, 1, (frameWidth * frameHeight) / 4, yuvFile);
			fwrite(vBuf, 1, (frameWidth * frameHeight) / 4, yuvFile);
		}





实验结果验证

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

处理后:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值