yuv420_jpg --- 借助于rgb

目的:yuv420数据转换成jpg数据

网上例子:bmp/jpg格式互换的例子, yuv422-->jpg 的例子。

思路:模仿422->jpg的例子, 提取yuv420的rgb值进行转换。

依赖: libjpeg开源库,http://www.ijg.org/。

编译: gcc -o XXX  代码.c  -ljpeg


代码:

#include <unistd.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdio.h>  
#include <sys/ioctl.h>  
#include <stdlib.h>  
#include <sys/mman.h>  
#include <linux/types.h>  
#include <linux/videodev2.h>  
#include <setjmp.h>  
#include <jpeglib.h>

typedef int BOOL;  

#define  TRUE    1  
#define  FALSE    0  

#define WIDTH 2432
#define HEIGHT 2048

unsigned char rgb[2432*2048*3] = {0,};
unsigned char yuv_src[2432*2048*3/2] = {0,};
void yuv420_to_rgb24()
{
    FILE* fp = fopen("420-2432.yuv", "rb");
    int ret = 0;
    int r1,g1,b1,r2,g2,b2;
    char* ptr = rgb;

    fread(yuv_src, 1, WIDTH*HEIGHT*2, fp);
    unsigned char* y_ou = yuv_src;  
    unsigned char* y_ji = yuv_src+ WIDTH;
    unsigned char* uv_start = yuv_src + WIDTH*HEIGHT;

    int i = 0, j=0;
    unsigned char y0, y1,u0,v0;
    for(i=0; i < HEIGHT/2; i++){
        /*处理偶行*/
        for(j = 0; j< WIDTH/2; j++){
            y0 = *y_ou ++;
            y1 = *y_ou ++;
            //u0 = *uv_start++;
            //v0 = *uv_start++;

            v0 = *uv_start++;
            u0 = *uv_start++;
            r1 = y0 + 1.042*(v0-128);
            g1 = y0 - 0.34414*(u0-128) - 0.71414*(v0-128);
            b1 = y0 + 1.772*(u0-128);

            r2 = y1 + 1.042*(v0-128);
            g2 = y1 - 0.34414*(u0-128) - 0.71414*(v0-128);
            b2 = y1 + 1.772*(u0-128);
            if(r1<0) r1 = 0; else if(r1>255) r1 = 255;
            if(g1<0) g1 = 0; else if(g1>255) g1 = 255;
            if(b1<0) b1 = 0; else if(b1>255) b1 = 255;
            if(r2<0) r2 = 0; else if(r2>255) r2 = 255;
            if(g2<0) g2 = 0; else if(g2>255) g2 = 255;
            if(b2<0) b2 = 0; else if(b2>255) b2 = 255;

            *ptr = (unsigned char)b1;ptr++;
            *ptr = (unsigned char)g1;ptr++;
            *ptr = (unsigned char)r1;ptr++;
            *ptr = (unsigned char)b2;ptr++;
            *ptr = (unsigned char)g2;ptr++;
            *ptr = (unsigned char)r2;ptr++;
        }
        
        uv_start -= WIDTH;
        /*处理奇行*/
        for(j=0; j<WIDTH/2; j++){
            y0 = *y_ji ++;
            y1 = *y_ji ++;
            v0 = *uv_start++;
            u0 = *uv_start++;

            r1 = y0 + 1.042*(v0-128);
            g1 = y0 - 0.34414*(u0-128) - 0.71414*(v0-128);
            b1 = y0 + 1.772*(u0-128);

            r2 = y1 + 1.042*(v0-128);
            g2 = y1 - 0.34414*(u0-128) - 0.71414*(v0-128);
            b2 = y1 + 1.772*(u0-128);
            if(r1<0) r1 = 0; else if(r1>255) r1 = 255;
            if(g1<0) g1 = 0; else if(g1>255) g1 = 255;
            if(b1<0) b1 = 0; else if(b1>255) b1 = 255;
            if(r2<0) r2 = 0; else if(r2>255) r2 = 255;
            if(g2<0) g2 = 0; else if(g2>255) g2 = 255;
            if(b2<0) b2 = 0; else if(b2>255) b2 = 255;

            *ptr = (unsigned char)b1;ptr++;
            *ptr = (unsigned char)g1;ptr++;
            *ptr = (unsigned char)r1;ptr++;
            *ptr = (unsigned char)b2;ptr++;
            *ptr = (unsigned char)g2;ptr++;
            *ptr = (unsigned char)r2;ptr++;
        }
        y_ou += WIDTH;
        y_ji += WIDTH;
    }

    return ;
}

BOOL encode_jpeg(char *lpbuf,int width,int height, int quality)  
{  
    struct jpeg_compress_struct cinfo ;  
    struct jpeg_error_mgr jerr ;  
    JSAMPROW  row_pointer[1] ;  
    int row_stride ;  
    char *buf=NULL ;  
    int x ;  

    FILE *fptr_jpg = fopen ("f.jpg","wb");//注意这里为什么用fopen而不用open  
    if(fptr_jpg==NULL)  
    {  
        printf("Encoder:open file failed!/n") ;  
        return FALSE;  
    }  

    cinfo.err = jpeg_std_error(&jerr);  
    jpeg_create_compress(&cinfo);  
    jpeg_stdio_dest(&cinfo, fptr_jpg);  

    cinfo.image_width = width;  
    cinfo.image_height = height;  
    cinfo.input_components = 3;  
    cinfo.in_color_space = JCS_RGB;  

    jpeg_set_defaults(&cinfo);  

    jpeg_set_quality(&cinfo, quality,TRUE);  
    jpeg_start_compress(&cinfo, TRUE);  

    row_stride = width * 3;  
    buf=malloc(row_stride) ;  
    row_pointer[0] = buf;  
    while (cinfo.next_scanline < height)  
    {  
        for (x = 0; x < row_stride; x+=3)  
        {  
            buf[x]   = lpbuf[x];  
            buf[x+1] = lpbuf[x+1];  
            buf[x+2] = lpbuf[x+2];  

        }  
        jpeg_write_scanlines (&cinfo, row_pointer, 1);//critical  
        lpbuf += row_stride;  
    }  

    jpeg_finish_compress(&cinfo);  
    fclose(fptr_jpg);  
    jpeg_destroy_compress(&cinfo);  
    free(buf) ;  
    return TRUE ;  

}    


int main(int argc, char* argv[])  
{  
    struct timeval tv;
    gettimeofday(&tv, NULL);
    printf("-------------- now: sec %d usec %d  \n",    (int)tv.tv_sec, (int)tv.tv_usec);
    yuv420_to_rgb24();
    encode_jpeg(rgb,2432,2048, atoi(argv[1])); //RGB24 to Jpeg  
    gettimeofday(&tv, NULL);
    printf("-------------- now: sec %d usec %d  \n",    (int)tv.tv_sec, (int)tv.tv_usec);
    printf("save JPEG OK\n");  
    return(TRUE);  
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值