图像处理 yuyv转rgb,rgb转jpeg,yuyv转yuv420, yuyv转jpeg

说明:将图片转到jpeg(我用的是jpegsrc.v9d.tar.gz),需要用到libjpeg库,下载目录http://www.ijg.org/,

安装方法:

1.  ./configure   --prefix=目录

2. make

3. make install

 

yuyv转rgb:

void yuv_to_rgb(unsigned char *yuv, unsigned char *rgb)
{
    unsigned int i;
    unsigned char* y0 = yuv + 0;
    unsigned char* u0 = yuv + 1;
    unsigned char* y1 = yuv + 2;
    unsigned char* v0 = yuv + 3;

    unsigned  char* r0 = rgb + 0;
    unsigned  char* g0 = rgb + 1;
    unsigned  char* b0 = rgb + 2;
    unsigned  char* r1 = rgb + 3;
    unsigned  char* g1 = rgb + 4;
    unsigned  char* b1 = rgb + 5;

    float rt0 = 0, gt0 = 0, bt0 = 0, rt1 = 0, gt1 = 0, bt1 = 0;

    for(i = 0; i <= (IMAGE_W * IMAGE_H) / 2 ;i++)
    {
        bt0 = 1.164 * (*y0 - 16) + 2.018 * (*u0 - 128);
        gt0 = 1.164 * (*y0 - 16) - 0.813 * (*v0 - 128) - 0.394 * (*u0 - 128);
        rt0 = 1.164 * (*y0 - 16) + 1.596 * (*v0 - 128);

        bt1 = 1.164 * (*y1 - 16) + 2.018 * (*u0 - 128);
        gt1 = 1.164 * (*y1 - 16) - 0.813 * (*v0 - 128) - 0.394 * (*u0 - 128);
        rt1 = 1.164 * (*y1 - 16) + 1.596 * (*v0 - 128);


        if(rt0 > 250)      rt0 = 255;
        if(rt0< 0)        rt0 = 0;

        if(gt0 > 250)     gt0 = 255;
        if(gt0 < 0)    gt0 = 0;

        if(bt0 > 250)    bt0 = 255;
        if(bt0 < 0)    bt0 = 0;

        if(rt1 > 250)    rt1 = 255;
        if(rt1 < 0)    rt1 = 0;

        if(gt1 > 250)    gt1 = 255;
        if(gt1 < 0)    gt1 = 0;

        if(bt1 > 250)    bt1 = 255;
        if(bt1 < 0)    bt1 = 0;

        *r0 = (unsigned char)rt0;
        *g0 = (unsigned char)gt0;
        *b0 = (unsigned char)bt0;

        *r1 = (unsigned char)rt1;
        *g1 = (unsigned char)gt1;
        *b1 = (unsigned char)bt1;

        yuv = yuv + 4;
        rgb = rgb + 6;
        if(yuv == NULL)
            break;

        y0 = yuv;
        u0 = yuv + 1;
        y1 = yuv + 2;
        v0 = yuv + 3;

        r0 = rgb + 0;
        g0 = rgb + 1;
        b0 = rgb + 2;
        r1 = rgb + 3;
        g1 = rgb + 4;
        b1 = rgb + 5;
    }
}

rgb转jpeg:

long rgb_to_jpeg(unsigned char *rgb, unsigned char *jpeg)
{
    size_t jpeg_size;
    struct jpeg_compress_struct jcs;
    struct jpeg_error_mgr jem;
    JSAMPROW row_pointer[1];
    int row_stride;

    jcs.err = jpeg_std_error(&jem);
    jpeg_create_compress(&jcs);

    jpeg_mem_dest(&jcs, &jpeg, &jpeg_size);//就是这个函数!!!!!!!

    jcs.image_width = IMAGE_W;
    jcs.image_height = IMAGE_H;

    jcs.input_components = 3;//1;
    jcs.in_color_space = JCS_RGB;//JCS_GRAYSCALE;

    jpeg_set_defaults(&jcs);
    jpeg_set_quality(&jcs, 180, TRUE);

    jpeg_start_compress(&jcs, TRUE);
    row_stride =jcs.image_width * 3;

    while(jcs.next_scanline < jcs.image_height){//对每一行进行压缩
        row_pointer[0] = &rgb[jcs.next_scanline * row_stride];
        (void)jpeg_write_scanlines(&jcs, row_pointer, 1);
    }
    jpeg_finish_compress(&jcs);
    jpeg_destroy_compress(&jcs);

#ifdef JPEG    //jpeg 保存,测试用
    FILE *jpeg_fd;

    jpeg_fd = fopen("./jpeg.jpg","w");
    if(jpeg_fd < 0 ){
        perror("open jpeg.jpg failed!\n");
        exit(-1);
    }

    fwrite(jpeg, jpeg_size, 1, jpeg_fd);
    fclose(jpeg_fd);
#endif
    return jpeg_size;
}

yuyv转yuv420:

int YUV422To420(unsigned char *yuv422, unsigned char *yuv420, int width, int height)
{

       int ynum=width*height;
       int i,j,k=0;
    //得到Y分量
       for(i=0;i<ynum;i++){
           yuv420[i]=yuv422[i*2];
       }
    //得到U分量
       for(i=0;i<height;i++){
           if((i%2)!=0)continue;
           for(j=0;j<(width/2);j++){
               if((4*j+1)>(2*width))break;
               yuv420[ynum+k*2*width/4+j]=yuv422[i*2*width+4*j+1];
                       }
            k++;
       }
       k=0;
    //得到V分量
       for(i=0;i<height;i++){
           if((i%2)==0)continue;
           for(j=0;j<(width/2);j++){
               if((4*j+3)>(2*width))break;
               yuv420[ynum+ynum/4+k*2*width/4+j]=yuv422[i*2*width+4*j+3];

           }
            k++;
       }

       return 1;
}

yuv420转jpeg:待测试

uint32_t yuv420sp_to_jpg(int width, int height, unsigned char *inputYuv,unsigned char *outJpeg)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    int i = 0, j = 0;
    unsigned char *pY, *pU, *pV;
    unsigned char yuvbuf[width * 3];
    unsigned long outSize;
    cinfo.err = jpeg_std_error(&jerr);//用于错误信息
    jpeg_create_compress(&cinfo);  //初始化压缩对象
    jpeg_mem_dest(&cinfo, &outJpeg, &outSize);
    cinfo.image_width = width;//设置输入图片宽度
    cinfo.image_height = height;//设置图片高度
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_YCbCr;//设置输入图片的格式,支持RGB/YUV/YCC等等
    cinfo.dct_method = JDCT_FLOAT;
    jpeg_set_defaults(&cinfo);//其它参数设置为默认的!
    jpeg_set_quality(&cinfo, 40, TRUE);//设置转化图片质量,范围0-100
    jpeg_start_compress(&cinfo, TRUE);
    pY = inputYuv ;
    pU = inputYuv +1 ;
    pV = inputYuv + 3;
    j = 1;
    while (cinfo.next_scanline < cinfo.image_height) {
        int index = 0;
        for (i = 0; i < width; i += 2){//输入的YUV图片格式为标准的YUV444格式,所以需要把YUV420转化成YUV444.
            yuvbuf[index++] = *pY;
            yuvbuf[index++] = *pU;
            yuvbuf[index++] = *pV;
            pY += 2;
            yuvbuf[index++] = *pY;
            yuvbuf[index++] = *pU;
            yuvbuf[index++] = *pV;
            pY += 2;
            pU += 4;
            pV += 4;
        }
        row_pointer[0] = yuvbuf;
        (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);//单行图片转换压缩
        j++;
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    fwrite(outJpeg, outSize, 1, jpeg_fd);
    fclose(jpeg_fd);

    return (uint32_t)outSize;
}

yuyv转jpeg:

#define IMAGE_W 1280
#define IMAGE_H 720

#define OUTPUT_BUF_SIZE 4096

typedef struct {
    struct jpeg_destination_mgr pub;
    JOCTET * buffer;
    unsigned char *outbuffer;
    int outbuffer_size;
    unsigned char *outbuffer_cursor;
    int *written;
}mjpg_destination_mgr;

typedef mjpg_destination_mgr *mjpg_dest_ptr;

METHODDEF(void) init_destination(j_compress_ptr cinfo) {
    mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
    dest->buffer =(JOCTET *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE*sizeof(JOCTET));
    *(dest->written) = 0;
    dest->pub.next_output_byte = dest->buffer;
    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}

METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo) {
    mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
    memcpy(dest->outbuffer_cursor, dest->buffer, OUTPUT_BUF_SIZE);
    dest->outbuffer_cursor += OUTPUT_BUF_SIZE;
    *(dest->written) += OUTPUT_BUF_SIZE;
    dest->pub.next_output_byte = dest->buffer;
    dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
    return TRUE;
}

METHODDEF(void) term_destination(j_compress_ptr cinfo) {
    mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
    size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
    /* Write any data remaining in the buffer */
    memcpy(dest->outbuffer_cursor, dest->buffer, datacount);
    dest->outbuffer_cursor += datacount;
    *(dest->written) += datacount;
}

void dest_buffer(j_compress_ptr cinfo, unsigned char *buffer, int size, int *written) {
    mjpg_dest_ptr dest;
    if(cinfo->dest == NULL) {
        cinfo->dest =(struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(mjpg_destination_mgr));
    }

    dest =(mjpg_dest_ptr)cinfo->dest;
    dest->pub.init_destination = init_destination;
    dest->pub.empty_output_buffer = empty_output_buffer;
    dest->pub.term_destination = term_destination;
    dest->outbuffer = buffer;
    dest->outbuffer_size = size;
    dest->outbuffer_cursor = buffer;
    dest->written = written;
}

//......YUYV.....JPEG..
int compress_yuyv_to_jpeg(unsigned char *buf, unsigned char *buffer, int size, int quality)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    unsigned char *line_buffer, *yuyv;
    int z;
    static int written;
    //int count = 0;
    //printf("%s\n", buf);
    line_buffer = (unsigned char*)calloc(IMAGE_W * 3, 1);
    yuyv = buf;
    printf("compress start...\n");
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    /* jpeg_stdio_dest(&cinfo, file); */
    dest_buffer(&cinfo, buffer, size, &written);
    cinfo.image_width = IMAGE_W;
    cinfo.image_height = IMAGE_H;
    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);
    z = 0;
    while(cinfo.next_scanline < IMAGE_H) {
        int x;
        unsigned char *ptr = line_buffer;
        for(x = 0; x < IMAGE_W; x++) {
            int r, g, b;
            int y, u, v;
            if(!z)
                y = yuyv[0] << 8;
            else
                y = yuyv[2] << 8;
            u = yuyv[1] - 128;
            v = yuyv[3] - 128;
            r =(y +(359 * v))>> 8;
            g =(y -(88 * u) -(183 * v)) >> 8;
            b =(y +(454 * u)) >> 8;
            *(ptr++) =(r > 255) ? 255 :((r < 0) ? 0 : r);
            *(ptr++) =(g > 255) ? 255 :((g < 0) ? 0 : g);
            *(ptr++) =(b > 255) ? 255 :((b < 0) ? 0 : b);
            if(z++) {
                z = 0;
                yuyv += 4;
            }
        }
        row_pointer[0] = line_buffer;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    free(line_buffer);
    return(written);
}

使用方法:
compress_yuyv_to_jpeg(buf, buffer,(IMAGE_W * IMAGE_H), 80);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值