[数据压缩] 实验二 bmp - YUV

一、实验目的

1.理解图像文件的基本组成

2.掌握结构体作为复杂数据对象的用法。进一步熟悉由问题到程序的解决方案,并掌握编程细节:如内存分配、倒序读写、字节序、文件读写过程等

二、实验原理

典型的 BMP 图像文件由四部分组成:
(1)位图头文件数据结构,包含 BMP 图像文件的类型、显示内容等信息;

(2)位图信息数据结构,包含有 BMP 图像的宽、高、压缩方法,以及定义颜色等信息;

在这里插入图片描述

 

(3)调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的 BMP)就不需要调色板;

在这里插入图片描述

 

(4)位图数据,根据 BMP 位图使用的位数不同而不同,在 24 位图中直接使用 RGB,而其他的小于 24 位的使用调色板中颜色索引值。

  • bmp图像规定每一扫描行的字节数必须是4的整数倍,即以DWORD对齐。(如不满4的整数倍,则采取补0处理)
  • 对于倒向DIB,扫描行是由底向上存储的


三、实现代码

头文件 bmp2yuv.h

int RGB2YUV (int x_dim, int y_dim, void *bmp, int flip, void *y_out, void *u_out, void *v_out);

void InitLookupTable();

bmp2yuv.cpp

    if (!flip) 
{
		for (j = 0; j < y_dim; j ++)
		{
			y = y_buffer + (y_dim - j - 1) * x_dim;
			u = u_buffer + (y_dim - j - 1) * x_dim;
			v = v_buffer + (y_dim - j - 1) * x_dim;
			
            for (i = 0; i < x_dim; i ++)
        
            {
				g = b + 1;
				r = b + 2;
				*y = (unsigned char)(  RGBYUV02990[*r] + RGBYUV05870[*g] +RGBYUV01140[*b]);
				*u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2+ 128);
				*v = (unsigned char)(  (*r)/2- RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
				b += 3;
				y ++;
				u ++;
				v ++;
			}
		}
}

主干代码 main.cpp

结构体变量

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

BITMAPFILEHEADER File_header;  
BITMAPINFOHEADER Info_header;

	

启动bmp文件

	bmpFile = fopen(bmpFileName, "rb");
		if (bmpFile == NULL)
		{
			printf("cannot find bmp file\n");
			exit(1);
		}
		else
		{
			printf("The input bmp file is %s\n", bmpFileName);
		}

读取头部数据

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

调用bmp2yuv,写入数据

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

		free(bmpBuf);
		free(yBuf);
		free(uBuf);
		free(vBuf);

		fclose(bmpFile);	
	}

三、结果验证

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值