数据压缩实验二 图像文件的读写和转换(bmp转yuv)

来源:互联网 发布:win10 windows安全性 编辑:程序博客网 时间:2024/05/17 02:15

一、实验原理

图像存储时一般由两部分组成:图像说明部分和图 像数据部分
图像说明部分:图像的格式、深度、高度、宽度、调色板、 压缩方法等
图像数据部分:描述图像每个像素的数据

1.BMP图像文件格式

位图文件(Bitmap-File,BMP)格式是Windows采 用的图像文件存储格式,在Windows环境下运行的 所有图像处理软件都支持这种格式。BMP位图文件 默认的文件扩展名是bmp或者dib。

BMP文件大体上分为四个部分:

位图文件头BITMAPFILEHEADER 位图信息头BITMAPINFOHEADER 调色板Palette 实际的位图数据ImageData

对于一种文件的格式,C语言中往往以结构体的方式描述,因此注意工程中的结构体是十分重要的。
(1)位图头文件数据结构

typedef struct tagBITMAPFILEHEADER {    WORD bfType; /* 说明文件的类型 */      DWORD bfSize; /* 说明文件的大小,用字节为单位 注意字节序*/      WORD bfReserved1; /* 保留,设置为0 */      WORD bfReserved2; /* 保留,设置为0 */      DWORD bfOffBits; /* 说明从BITMAPFILEHEADER结构开始到实际的图像数据之间的字节偏移量 */  } BITMAPFILEHEADER;

(2)位图信息数据结构

typedef struct tagBITMAPINFOHEADER{    DWORD biSize; /* 说明结构体所需字节数 */    LONG biWidth; /* 以像素为单位说明图像的宽度 */    LONG biHeight; /* 以像素为单位说明图像的高度 */    WORD biPlanes; /* 说明位面数,必须为1 */    WORD biBitCount; /* 说明位数/像素,1、2、4、8、24 */    DWORD biCompression; /* 说明图像是否压缩及压缩类型BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS */    DWORD biSizeImage; /* 以字节为单位说明图像大小,必须是4的整数倍*/    LONG biXPelsPerMeter; /*目标设备的水平分辨率,像素/米 */    LONG biYPelsPerMeter; /*目标设备的垂直分辨率,像素/米 */    DWORD biClrUsed; /* 说明图像实际用到的颜色数,如果为0,则颜色数为2的biBitCount次方 */    DWORD biClrImportant; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。*/} BITMAPINFOHEADER;

(3)调色板
调色板实际上是一个数组,它所包含的元素与位图 所具有的颜色数相同,决定于biClrUsed和biBitCount字 段。数组中每个元素的类型是一个RGBQUAD结构。真 彩色无调色板部分。

typedef struct tagRGBQUAD{    BYTE rgbBlue; /*指定蓝色分量*/    BYTE rgbGreen; /*指定绿色分量*/    BYTE rgbRed; /*指定红色分量*/    BYTE rgbReserved; /*保留,指定为0*/} RGBQUAD;

(4)图像数据字节阵列:即位图数据
紧跟在调色板之后的是图像数据字节阵列。对于用到调 色板的位图,图象数据就是该象素颜色在调色板中的索引值 (逻辑色)。对于真彩色图,图象数据就是实际的R、G、B 值。

2.需要注意的地方

(1)DWORD 对齐
图像的每一扫描行由表示图像像素的连续的字节组成,每一行的字节数取决于图像的颜色数目和用像素表示的图像宽
度。规定每一扫描行的字节数必需是4的整倍数,也就是DWORD对齐的。写入位图文件数据时,如果图像每行像素字节总数[宽 X biBiCount % 8 != 0 ],系统会自动在每行最后填充若干0值使满足整数字节,接着,如果[每行像素字节数 % 4 != 0 ],系统会自动在每行最后填充若干字节0值使满足DWORD对齐。所以我们对位图加载处理时要注意判断每行数据是否有0值填充,若有0值填充则从位图中读取数据的过程中要注意指针偏移量和即时跳转。

(2)自下而上扫描
扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。(只针对于倒向DIB,如果是正向DIB,则扫描行是由顶向下存储)

(3)字节序
计算机系统存储数据采用的字节序有两种:小尾字节序(Little Endian)和大尾字节序(Big Endian)。以Intel处理器为代表大多数采用小端字节序,”低位在前高位在后“既地址低位存储值的低位,地址高位存储值的高位;以Motorola处理器为代表大多数使用大端字节序,”高位在前低位在后“即地址低位存储值的高位,地址高位存储值的低位。BMP文件中仅除了文件头中文件类型WORD bfType为大端字节序,剩余结构体内的定义均是小端字节序。

(4)掩码组
调色板信息中指示了RGB比特位的掩码组信息。因为图像深度可选为1、4、8、16、24、32bit,所以不同深度的RGB比特位自然不同。
以bmp位图中使用16bit为例,位运算的图示:
这里写图片描述
若读入的BMP位图的biBiCount为8bit或更小,类似的需要位的移位、与操作。
再以2bit图像举例,其数据块中的第一个字节,对应着第一个像素的索引值为:b’xx zz zz zz,其中只有头两位包含该像素的索引信息,而后六位为其他像素的索引信息。这时候需要与b’11 00 00 00=0xC0相与,再进行6位右移,得到b’00 00 00 xx=index,这便是其对应的索引值,代入pRGB[index]获得其对应的RGB分量值。
当处理像素是第二个像素是,其对应的索引值应为该字节中的第五第六位,即b’zz xx zz zz,这时候掩码值也相应跟着位移,遂引入turn–掩码位移变量,turn可用作循环判断用,当turn为零时——说明该字节中所有像素信息已读取完,可以结束循环,进行下一个字节的读取。
同时,应注意到右移的位数也发生了变换,引入shiftcnt变量,用于不同像素点需位移的长度。每进行一次像素数据读取后,shiftcnt++,因为下一个像素(不是该字节最后一个像素时)需要位移的位数减少了shift*biBitCount个。

二、实验流程

(1)初始化:打开文件,定义变量建立缓冲区
(2)解析BMP文件,抽取或生成RGB数据写入缓冲区
(3)调用RGB2YUV函数进行数据转换
(4)写入YUV文件,关闭文件,释放缓冲区
这里写图片描述

三、实验具体算法代码

1.BMP2YUV.h

#ifndef BMP2YUV_H_#define BMP2YUV_H_//define mask structtypedef struct bit32Mask{    unsigned int rgbRed;    unsigned int rgbGreen;    unsigned int rgbBlue;       unsigned int reserved;}Mas32;typedef struct bit16Mask{    unsigned int rgbRed;    unsigned int rgbGreen;    unsigned int rgbBlue;}Mas16;int BMP2RGB32bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf, void *mask);int BMP2RGB24bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf);int BMP2RGB16bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf,void *mask);int BMP2RGBNOT24bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf, void *pRGB);int RGB2YUV(int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip);void InitLookupTable();void adjust(unsigned char *b, unsigned char *g, unsigned char *r, unsigned char *y, unsigned char *u, unsigned char  *v);#endif

2.main.c

#include <stdio.h>#include <stdlib.h>#include <windows.h> #include <math.h> #include "bmp2yuv.h"#define u_int8_t    unsigned __int8#define u_int       unsigned __int32#define u_int32_t   unsigned __int32int main(int argc,char **argv){    int count;    BITMAPFILEHEADER File_header;    BITMAPINFOHEADER Info_header;    RGBQUAD *pRGB = NULL;    FILE* bmp = NULL;    FILE* yuvFile = NULL;       Mas16 *mask16 = NULL;    Mas32 *mask32 = NULL;    u_int8_t* yBuf = NULL;    u_int8_t* uBuf = NULL;    u_int8_t* vBuf = NULL;    u_int8_t* rgbBuf = NULL;    u_int8_t* bmpBuf = NULL;    u_int8_t* mask = NULL;    u_int frameWidth;       /* --width=<uint> */    u_int frameHeight;    u_int bitcount;    u_int py;    u_int m;    u_int8_t i;    int sum = 0;    char bmpf[][50] = { "park.bmp", "tree.bmp", "girlstwo.bmp", "02.bmp", "bea.bmp", "street.bmp" };    char yuvname[50] = "CometoYUV.yuv";    FILE *yuv=NULL;    int framenumber;    /* build the RAW file */    fopen_s(&yuv, yuvname, "wb+");    if (yuv == NULL)    {        printf("Fail to Build yuv file\n");        exit(0);    }    else    {        printf("The output rgb file is %s\n", yuvname);        printf("\n");        printf("-------------------------------------------------------------------------\n");    }    for (i = 0; i<6; i++)    {        count = 0;        framenumber = atoi(argv[i + 1]);        //open the bmp file        fopen_s(&bmp, bmpf[i], "rb");        if (!bmp)        {            printf("cannot find the specific file %s:\n", bmpf[i]);            exit(0);        }        else        {            printf("The input bmp file:   %s\n", bmpf[i]);        }        if (!framenumber)        {            printf("\n写入帧数:0\n");            continue;        }        else        {            if (fread(&File_header, sizeof(BITMAPFILEHEADER), 1, bmp) != 1)            {                printf("read file header error!");                exit(0);            }            if (File_header.bfType != 0x4D42)            {                printf("Not bmp file!");                exit(0);            }            //printf("this is a 0x%04X:\n", File_header.bfType);                if (fread(&Info_header, sizeof(BITMAPINFOHEADER), 1, bmp) != 1)            {                printf("read info header error!");                exit(0);            }            //  end read header            frameWidth = Info_header.biWidth;           /* --width=<uint> */            frameHeight = Info_header.biHeight;            py = File_header.bfOffBits;            bitcount = Info_header.biBitCount;            /* get an output buffer for a frame */            if ((frameWidth*bitcount % 8 == 0) && (frameWidth*bitcount / 8 % 4 == 0))//DWORD 对齐            {                yBuf = (u_int8_t*)malloc(frameWidth * frameHeight);                uBuf = (u_int8_t*)malloc((frameWidth * frameHeight) / 4);                vBuf = (u_int8_t*)malloc((frameWidth * frameHeight) / 4);                /* get an input buffer for a frame */                bmpBuf = (u_int8_t*)malloc(frameWidth * frameHeight * bitcount / 8);                /* get an output buffer for a frame */                rgbBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 3);                               if (rgbBuf == NULL || yBuf == NULL || uBuf == NULL || vBuf == NULL || bmpBuf == NULL)                {                    printf("no enought memory\n");                    exit(1);                }                ////////////////////////////////BMP 2 RGB                while (framenumber)                {                    fseek(bmp, py, SEEK_SET);                    if (!fread(bmpBuf, 1, frameWidth * frameHeight * bitcount / 8, bmp))                    {                        printf("the image has problems!");                        return 0;                    }                    if (bitcount == 32)                    {                        if (Info_header.biCompression==0)                        {                             if (BMP2RGB32bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf,0))                            {                                printf("32bit BMP2RGB program runs error!");                                return 0;                            }                                               }                        else if (Info_header.biCompression == 3)                        {                            //取掩码组                            m = 4*4;                            mask32 = (Mas32*)malloc(sizeof(Mas32));                            fseek(bmp, sizeof(BITMAPFILEHEADER) + Info_header.biSize - m, SEEK_SET);                            fread(mask32, sizeof(Mas32),1, bmp);                            if (BMP2RGB32bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf, mask32))                            {                                printf("32bit BMP2RGB program runs error!");                                return 0;                            }                        }                    }                    else if (bitcount == 24)                    {//真彩位图                        if (BMP2RGB24bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf))                        {                            printf("24bit BMP2RGB program runs error!");                            return 0;                        }                    }                    else if (bitcount == 16)                    {                                               //16bit BMP RGB比特位根据biCompression确定                        if (Info_header.biCompression == 0)//555                        {                            if (BMP2RGB16bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf, 0))                            {                                printf("16bit BMP2RGB program runs error!");                                return 0;                            }                        }                        else if (Info_header.biCompression == 3)                        {                            //取掩码组                            m = 4 * 3;                            mask16 = (Mas16*)malloc(sizeof(Mas16));                            fseek(bmp, py-m, SEEK_SET);                            fread(mask16, 1, m, bmp);                                                       if (BMP2RGB16bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf, mask16))                            {                                printf("16bit BMP2RGB program runs error!");                                return 0;                            }                        }                                           }                    else                    {                                               if ((py - sizeof(BITMAPFILEHEADER) - Info_header.biSize) == sizeof(RGBQUAD)*pow(2, (double)bitcount))                        {//1、2、4、8 bit 有调色板部分                            m = (unsigned int)pow(2, (double)bitcount);                            pRGB = (RGBQUAD *)malloc(sizeof(RGBQUAD)*m);                            fseek(bmp, sizeof(BITMAPFILEHEADER) + Info_header.biSize, SEEK_SET);                            fread(pRGB, sizeof(RGBQUAD), m, bmp);                            if (BMP2RGBNOT24bit(bitcount, frameWidth, frameHeight, bmpBuf, rgbBuf, pRGB))                            {                                printf("BMP 2 RGB program runs error!");                                return 0;                            }                        }                                           }                    /////////////////////////////RGB2YUV                    if (RGB2YUV(frameWidth, frameHeight, rgbBuf, yBuf, uBuf, vBuf, 0/*flip=0*/))//bmp图像格式从最后一行起逐行扫描                    {                        printf("RGB2YUV program runs error!");                        return 0;                    }                    fwrite(yBuf, 1, frameWidth * frameHeight, yuv);                    fwrite(uBuf, 1, (frameWidth * frameHeight) / 4, yuv);                    fwrite(vBuf, 1, (frameWidth * frameHeight) / 4, yuv);                    printf("\r...%d", ++count);                    framenumber--;                }                printf("\n写入帧数:%u   %ux%u(%d bit)\n", count, frameWidth, frameHeight, bitcount);                sum += count;                printf("\n");                printf("\n");            }        }                   }    printf("%d帧YUV写入成功!\n",sum);    /* cleanup */    fclose(bmp);    fclose(yuv);    //free the memory       if (yBuf)   { free(yBuf); }    if (uBuf)   { free(uBuf); }    if (vBuf)   { free(vBuf); }    if (rgbBuf) { free(rgbBuf); }    if (bmpBuf) { free(bmpBuf); }    if (pRGB)   { free(pRGB); }    if (mask16) { free(mask16); }    if (mask32)  { free(mask32); }    return 0;}

3.BMP2RGB.c

#include "stdlib.h"#include "bmp2yuv.h"#include <windows.h> #include <math.h> int BMP2RGB32bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf, void *mask){    long i;    unsigned char *bmp, *rgb;    Mas32 *mas;    long size = x_dim*y_dim;    bmp = (unsigned char *)bmpbuf;    rgb = (unsigned char *)rgbbuf;    mas = (Mas32 *)mask;    if (mask == NULL)    {        for (i = 0; i < size; i++)        {            *(rgb + 0) = *(bmp + 0);            *(rgb + 1) = *(bmp + 1);            *(rgb + 2) = *(bmp + 2);            rgb += 3;            bmp += 4;        }        return 0;    }    else    {//根据掩码确定RGB比特位        int Gkey, Bkey, Rkey;        if (mas->rgbGreen == 0)            Gkey= 0;        else if (mas->rgbGreen == 0xFF000000)            Gkey = 3;        else if (mas->rgbGreen == 0xFF0000)            Gkey = 2;        else if (mas->rgbGreen == 0xFF00)            Gkey = 1;        else            return 1;        if (mas->rgbBlue == 0)           Bkey = 0;        else if (mas->rgbBlue == 0xFF000000)            Bkey = 3;        else if (mas->rgbBlue == 0xFF0000)            Bkey = 2;        else if (mas->rgbBlue == 0xFF00)            Bkey = 1;        else            return 1;        if (mas->rgbRed == 0)            Rkey = 0;        else if (mas->rgbRed == 0xFF000000)            Rkey = 3;        else if (mas->rgbRed == 0xFF0000)            Rkey = 2;        else if (mas->rgbRed == 0xFF00)            Rkey = 1;        else            return 1;        for (i = 0; i < size; i++)        {            *(rgb + 0) = *(bmp + Bkey);            *(rgb + 1) = *(bmp + Gkey);            *(rgb + 2) = *(bmp + Rkey);            rgb += 3;            bmp += 4;        }        return 0;    }}int BMP2RGB24bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf){    long i;    unsigned char *rgb;// , *raw;    unsigned char *bmp;    long size = x_dim*y_dim;    rgb = (unsigned char *)rgbbuf;    bmp = (unsigned char *)bmpbuf;    for (i = 0; i < size*3; i++)    {        *(rgb + i) = *(bmp + i);    }    return 0;}int BMP2RGB16bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf, void *mask){    long loop;    unsigned char *Data, *rgbDataOut;    long size = x_dim*y_dim*bitcount / 8;    Data = (unsigned char*)bmpbuf;    rgbDataOut = (unsigned char*)rgbbuf;    Mas16 *mas;    mas = (Mas16 *)mask;    if (mask == NULL)    {        for (loop = 0; loop < size; loop += 2)        {            *rgbDataOut = (*(Data + loop) & 0x1F) << 3;            *(rgbDataOut + 1) = ((*(Data + loop) & 0xE0) >> 2) + ((*(Data + loop + 1) & 0x03) << 6);            *(rgbDataOut + 2) = (*(Data + loop + 1) & 0x7C) << 1;            rgbDataOut += 3;        }    }    else//555 OR 565决定于rgbGreen的比特位    {        if (mas->rgbGreen == 0x07E0)        {            for (loop = 0; loop < size; loop += 2)            {                *rgbDataOut = (*(Data + loop) & 0x1F) << 3;                *(rgbDataOut + 1) = ((*(Data + loop) & 0xE0) >> 3) + ((*(Data + loop + 1) & 0x07) << 5);                *(rgbDataOut + 2) = (*(Data + loop + 1) & 0xF8);                rgbDataOut += 3;            }        }        else        {            for (loop = 0; loop < size; loop += 2)            {                *rgbDataOut = (*(Data + loop) & 0x1F) << 3;                *(rgbDataOut + 1) = ((*(Data + loop) & 0xE0) >> 2) + ((*(Data + loop + 1) & 0x03) << 6);                *(rgbDataOut + 2) = (*(Data + loop + 1) & 0x7C) << 1;                rgbDataOut += 3;            }        }    }    return 0;}int BMP2RGBNOT24bit(int bitcount, int x_dim, int y_dim, void *bmpbuf, void *rgbbuf, void *ppRGB)//1\4\8 bit BMP{    unsigned char *rgb;    unsigned char *bmp;    unsigned char index;    bmp = (unsigned char *)bmpbuf;    rgb = (unsigned char *)rgbbuf;    int shiftCnt;    unsigned char mask;    long loop = 0;    unsigned char *Data, *rgbDataOut;    RGBQUAD* p;    long size = x_dim*y_dim*bitcount/8;    Data = (unsigned char*)bmpbuf;    rgbDataOut = (unsigned char*)rgbbuf;    p = (RGBQUAD*)ppRGB;    for (loop = 0; loop<size; loop++)    {        shiftCnt = 1;        mask = (unsigned char)pow(2, (double)bitcount) - 1;        mask = mask << (8-bitcount);        while (mask)        {            //索引号的确定            index = (mask == 0xFF) ? *(Data + loop) : (*(Data + loop) & mask) >> (8 - shiftCnt * bitcount);            *rgbDataOut = (p + index)->rgbBlue;            *(rgbDataOut + 1) = (p + index)->rgbGreen;            *(rgbDataOut + 2) = (p + index)->rgbRed;            if (bitcount == 8)                mask = 0;            else                mask >>= bitcount;            rgbDataOut += 3;            shiftCnt++;        }    }    return 0;}

4.RGB2YUV.c

#include "stdlib.h"#include "bmp2yuv.h"static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];static float RGBYUV01684[256], RGBYUV03316[256];static float RGBYUV04187[256], RGBYUV00813[256];int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip){    static int init_done = 0;    long i, j, size;    unsigned char *r, *g, *b;    unsigned char *y, *u, *v;    unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;    unsigned char *y_buffer, *u_buffer, *v_buffer;    unsigned char *sub_u_buf, *sub_v_buf;    if (init_done == 0)    {        InitLookupTable();        init_done = 1;    }    // check to see if x_dim and y_dim are divisible by 2    if ((x_dim % 2) || (y_dim % 2)) return 1;    size = x_dim * y_dim;    // allocate memory    y_buffer = (unsigned char *)y_out;    sub_u_buf = (unsigned char *)u_out;    sub_v_buf = (unsigned char *)v_out;    u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));    v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));    if (!(u_buffer && v_buffer))    {        if (u_buffer) free(u_buffer);        if (v_buffer) free(v_buffer);        return 2;    }    b = (unsigned char *)bmp;    y = y_buffer;    u = u_buffer;    v = v_buffer;    // convert RGB to YUV    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;                adjust(b, g, r, y, u, v);                b += 3;                y ++;                u ++;                v ++;            }        }    } else {        for (i = 0; i < size; i++)        {            g = b + 1;            r = b + 2;                      adjust(b, g, r, y, u,v);            b += 3;            y ++;            u ++;            v ++;        }    }    // subsample UV    for (j = 0; j < y_dim/2; j ++)    {        psu = sub_u_buf + j * x_dim / 2;        psv = sub_v_buf + j * x_dim / 2;        pu1 = u_buffer + 2 * j * x_dim;        pu2 = u_buffer + (2 * j + 1) * x_dim;        pv1 = v_buffer + 2 * j * x_dim;        pv2 = v_buffer + (2 * j + 1) * x_dim;        for (i = 0; i < x_dim/2; i ++)        {            *psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4;            *psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4;            psu ++;            psv ++;            pu1 += 2;            pu2 += 2;            pv1 += 2;            pv2 += 2;        }    }    free(u_buffer);    free(v_buffer);    return 0;}void InitLookupTable(){    int i;    for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;    for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;    for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;    for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;    for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;    for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;    for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;}void adjust(unsigned char *b, unsigned char *g, unsigned char *r, unsigned char *y, unsigned char *u, unsigned char  *v){    float temp = 0;    temp = (float)(RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);    temp = temp>235 ? 235 : temp;    temp = temp<16 ? 16 : temp;    *y = (unsigned char)temp;    temp = (float)(-RGBYUV01684[*r] - RGBYUV03316[*g] + (*b) / 2 + 128);    temp = temp>240 ? 240 : temp;    temp = temp<16 ? 16 : temp;    *u = (unsigned char)temp;    temp = (float)((*r) / 2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);    temp = temp>240 ? 240 : temp;    temp = temp<16 ? 16 : temp;    *v = (unsigned char)temp;}

四、实验结果

由命令行设置每幅图片播放帧数:4幅图片,每幅转成50帧yuv序列
这里写图片描述
执行结果如图所示:
这里写图片描述
不同比特位的bmp位图的对比:

biBitCount 原BMP图像 生成YUV序列中的一帧 24bit right-aligned $1600 8bit centered $12 4bit are neat $1 1bit are neat $1

五、实验总结

本次实验中应重点掌握的是文件格式的概念、字节序、缓冲区分配、结构体操作、倒序读写文件、函数定义等操作

1 0
原创粉丝点击