1. 程式人生 > >bmp圖片轉換為YUV422格式

bmp圖片轉換為YUV422格式

/*
 *以24位深bmp影象為例。即不帶調色盤,一個畫素又三個位元組構成,圖片解析度800*600
 *[0,1]bmp標示
 *[5:2]檔案大小 
 *[6:9]保留值=0
 *[12:10]bmp資料起始地址:左下角第一個畫素(B,G,R),左下角第二個畫素
 * */

#include 
#include 
#include 
#include 
#include 

#define BMP_PATH "/Mywork/123.bmp"
#define YUV_PATH "/Mywork/123.bin"

int main(int argc,char **argv)
{
        int fd;
        int length = 0;
        int i,n;
        char buf[1440000];   //有這麼多個畫素   600*800*3
        char yuv_buf[960000]; //yuyv影象佔的畫素數 600*800*2
        char begin_buf[] = {0x41,0x49,0x4d,0x47,0x10,0xa6,0x0e,0x00,0x20,0x03,0x58,0x02,0x01,0x01,0x00,0x00}; //自己新增的起始資訊

        fd = open(BMP_PATH,O_RDWR);
        if(fd < 0){
                perror("open error");
        }

        read(fd,buf,16);//先讀取16位元組資料 第10 11 12位描述的影象資料的起始地址
        //如36 00 00 表示資料起始地址是00 00 36即0x36開始。     

        /*for(i = 0;i < 16;i++){
                printf("%x |",(uint8_t)buf[i]);
        }
        */

        //確定bmp影象資料地址
        i = buf[10] + (buf[11]<<8) + (buf[12]<<16);

        lseek(fd,i,SEEK_SET);
        printf("begin :%x \n",i);

        for(i = 599;i >= 0;i--){
                length += read(fd,buf + i*800*3,800*3);
            printf("length:%d\n",length);

        //Y0U0Y1V0 Y2U1Y3V1 每次處理兩個畫素
        for(i = 0,n =0;i < length;i+=6,n+=4){

                yuv_buf[n] = RGB_Convert_Y(buf[i+2],buf[i+1],buf[i]);
                yuv_buf[n+1] = RGB_Convert_U(buf[i+2],buf[i+1],buf[i]);
                yuv_buf[n+2] = RGB_Convert_Y(buf[i+5],buf[i+4],buf[i+3]);
                yuv_buf[n+3] = RGB_Convert_V(buf[i+2],buf[i+1],buf[i]);
        }

        close(fd);
        fd = open(YUV_PATH,O_RDWR|O_CREAT|O_TRUNC);
        if(fd < 0){
                perror("error");
        }

        write(fd,begin_buf,16);
        write(fd,yuv_buf,800*600*2);
        close(fd);
}