yuv420 转换成 bmp
阅读原文时间:2023年07月16日阅读:2

源码如下:

// ConsoleApplication1.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h> 

#define XSIZE 1920
#define YSIZE 1080     

#define RGB_SIZE  XSIZE * YSIZE * 3
typedef unsigned char byte;

double YUV2RGB_CONVERT_MATRIX[3][3] = { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } };

void ConvertYUV2RGB(unsigned char *yuvFrame, unsigned char *rgbFrame, int width, int height)
{
    int uIndex = width * height;
    int vIndex = uIndex + ((width * height) >> 2);
    int gIndex = width * height;
    int bIndex = gIndex * 2;
    int temp, x, y;

    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            // R分量
            temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0][2]);
            rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
            // G分量
            temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1][1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1][2]);
            rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
            // B分量
            temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2][1]);
            rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
        }
    }
}

int  main(){
    int i, j, y, x;
    long width, height;
    unsigned char *data;
    unsigned char *image;   //用于存放读取的yuv数据
    unsigned char *image_bmp;

    FILE *fp_r;

    width = XSIZE;
    height = YSIZE;
    long int bytePerLine = width * 3;

    //申请空间
    image = (unsigned char *)malloc(width * height * 3 / 2);
    image_bmp = (unsigned char *)malloc(width * height * 3);
    data = (unsigned char*)malloc(bytePerLine * height);

    if ((NULL == image) || (image_bmp == NULL) || (data == NULL))
    {
        printf("faied to malloc the image\n");
        return -1;
    }

    /********读取yuv 文件***********/
    fp_r = fopen("test.yuv", "rb"); //打开yuv 文件
    if (NULL == fp_r)
    {
        printf("failed to open the fp_r\n");
        return -1;
    }

    fread(image, sizeof(unsigned char), XSIZE * YSIZE * 3 / 2, fp_r);
    fclose(fp_r);

    for (i = 0; i<width *height * 3; i++)
        *(image_bmp + i) = 255;

    //写bmp图片
    int gIndex = width * height;
    int bIndex = gIndex * 2;

    unsigned char header[54] = {
        0x42, 0x4d,       //WORD  bfType----------- [0,1]
        0, 0, 0, 0,      //DWORD bfSize----------- [2,3,4,5]
        0, 0,            //WORD  bfReserved1------ [6,7]
        0, 0,            //WORD  bfReserved2------ [8,9]
        54, 0, 0, 0,      //WORD  bfOffBits-------- [10,11,12,13]   

        40, 0, 0, 0,      //DWORD biSize----------- [14,15,16,17]
        0, 0, 0, 0,      //LONG  biWidth---------- [18,19,20,21]
        0, 0, 0, 0,      //LONG  biHeight--------- [22,23,24,25]
        1, 0,            //WORD  biplanes--------- [26,27]
        24, 0,            //WORD  biCount---------- [28,29]
        0, 0, 0, 0,      //DWORD biCompression---- [30,31,32,33]
        0, 0, 0, 0,      //DWORD biSizeImage------ [34,35,36,37]
        0, 0, 0, 0,      //LONG  biXPelsPerMeter-- [38,39,40,41]
        0, 0, 0, 0,      //LONG  biYPelsPerMeter-- [42,43,44,45]
        0, 0, 0, 0,      //DWORD biClrUsed-------- [46,47,48,49]
        0, 0, 0, 0       //DWORD biClrImportant--- [50,51,52,53]
    };
    long file_size = (long)width * (long)height * 3 + 54;
    header[2] = (unsigned char)(file_size & 0x000000ff);
    header[3] = (file_size >> 8) & 0x000000ff;
    header[4] = (file_size >> 16) & 0x000000ff;
    header[5] = (file_size >> 24) & 0x000000ff;

    header[18] = width & 0x000000ff;
    header[19] = (width >> 8) & 0x000000ff;
    header[20] = (width >> 16) & 0x000000ff;
    header[21] = (width >> 24) & 0x000000ff;

    header[22] = height & 0x000000ff;
    header[23] = (height >> 8) & 0x000000ff;
    header[24] = (height >> 16) & 0x000000ff;
    header[25] = (height >> 24) & 0x000000ff;

    char filename[6] = "1.bmp";

    ConvertYUV2RGB(image, image_bmp, width, height);

    for (y = height - 1, j = 0; y >= 0; y--, j++)
    {
        for (x = 0, i = 0; x < width; x++)
        {
            data[y * bytePerLine + i++] = image_bmp[bIndex + j * width + x];
            // B                    

            data[y * bytePerLine + i++] = image_bmp[gIndex + j * width + x];
            // G          

            data[y * bytePerLine + i++] = image_bmp[j * width + x];
            // R
        }
    }
    //sprintf(filename, "%d.bmp",1);   

    FILE *fp_w;
    if (!(fp_w = fopen(filename, "wb")))
        return -1;

    fwrite(header, sizeof(unsigned char), 54, fp_w);

    fwrite(data, sizeof(unsigned char), XSIZE * YSIZE * 3, fp_w);

    fclose(fp_w);
    free(image);
    return(0);
}