我的github: https://github.com/WHJWNAVY

YUYV格式转换为JPG格式函数

电子小制作 Ann, Pepper 4301℃


原创博客,转载注明出处。
使用说明:
本代码提取自MJPG-streamer库,依赖于libjpeg库,请用户自行安装。只提供了一个接口函数compress_yuyv_to_jpeg,用户只需调用该函数,传递正确的参数即可完成YUV到JPG的转换。
jpeg_utils.h

#ifndef __JPEG_UTILS_H_
#define __JPEG_UTILS_H_
/*****************************************************************************
 函 数 名  compress_yuyv_to_jpeg
 功能描述  : yuv格式转JPG格式
 输入参数  : const unsigned char* yuvbuf:存放YUV格式图像的BUF
             unsigned char *dstbuf:存放转换后的JPG图像的BUF
             int yuvbufsize:存放YUV格式图像的BUF的大小
             int height:图像的高度
             int width:图像的宽度        
             int quality:图像的质量0-100
 输出参数  : dstbuf
 返 回 值  转换后的JPEG图片的大小
 函数说明  
         1.: yuv2jpeg function is based on compress_yuyv_to_jpeg written by
              Gabriel A. Devenyi.
              It uses the destination manager implemented above to compress
              YUYV data to JPEG. Most other implementations use the
              “jpeg_stdio_dest” from libjpeg, which can not store compressed
              pictures to memory instead of a file.
         2.: video structure from v4l2uvc.c/h, destination dstbuf and buffersize
              the dstbuf must be large enough, no error/yuvbufsize checking is done!
         3.: the dstbuf will contain the compressed data
*****************************************************************************/
 

extern int compress_yuyv_to_jpeg
(
    
unsigned char* yuvbuf, 
    unsigned char* dstbuf, 
    int yuvbufsize, 
    int height, 
    int width, 
    int quality
);
 

#endif

 
jpeg_utils.c
 

/*******************************************************************************
# Linux-UVC streaming input-plugin for MJPG-streamer                           #
#                                                                              #
# This package work with the Logitech UVC based webcams with the mjpeg feature #
#                                                                              #
#   Orginally Copyright (C) 2005 2006 Laurent Pinchart &&  Michel Xhaard       #
#   Modifications Copyright (C) 2006  Gabriel A. Devenyi                       #
#   Modifications Copyright (C) 2007  Tom St?veken                             #
#                                                                              #
# This program is free software; you can redistribute it and/or modify         #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation; either version 2 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# This program is distributed in the hope that it will be useful,              #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with this program; if not, write to the Free Software                  #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    #
#                                                                              #
*******************************************************************************/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jpeglib.h>
#include “jpeg_utils.h”
#include “debug_msg.h”
 

#define OUTPUT_BUF_SIZE  4096
 

typedef struct
{
    struct jpeg_destination_mgr pub; /* public fields */
 
    
JOCTET *buffer;     /* start of buffer */
 
    
unsigned char *outbuffer;
    int outbuffer_size;
    unsigned char *outbuffer_cursor;
    int *written;
 

} mjpg_destination_mgr;
 

typedef mjpg_destination_mgr *mjpg_dest_ptr;
 
/******************************************************************************
Description.:
Input Value.:
Return Value:
******************************************************************************/
//METHODDEF(void) init_destination(j_compress_ptr cinfo)
void init_destination(j_compress_ptr cinfo)
{
    mjpg_dest_ptr dest = (mjpg_dest_ptr) cinfo->dest;
 

    
/* Allocate the output buffer — it will be released when done with image */
    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;
}
 
/******************************************************************************
Description.: called whenever local jpeg buffer fills up
Input Value.:
Return Value:
******************************************************************************/
//METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
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;
}
 

/******************************************************************************
Description.: called by jpeg_finish_compress after all data has been written.
              Usually needs to flush buffer.
Input Value.:
Return Value:
******************************************************************************/
//METHODDEF(void) term_destination(j_compress_ptr cinfo)
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;
}
 
/******************************************************************************
Description.: Prepare for output to a stdio stream.
Input Value.: buffer is the already allocated buffer memory that will hold
              the compressed picture. “size” is the size in bytes.
Return Value: –
******************************************************************************/
//GLOBAL(void) dest_buffer(j_compress_ptr cinfo, unsigned char *buffer, int size, int *written)
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;
}
 

/*****************************************************************************
 函 数 名  : compress_yuyv_to_jpeg
 功能描述  : yuv格式转JPG格式
 输入参数  : const unsigned char* yuvbuf:存放YUV格式图像的BUF
             unsigned char *dstbuf:存放转换后的JPG图像的BUF
             int yuvbufsize:存放YUV格式图像的BUF的大小
             int height:图像的高度
             int width:图像的宽度        
             int quality:图像的质量0-100
 输出参数  : dstbuf
 返 回 值  转换后的JPEG图片的大小
 函数说明  
         1.: yuv2jpeg function is based on compress_yuyv_to_jpeg written by
              Gabriel A. Devenyi.
              It uses the destination manager implemented above to compress
              YUYV data to JPEG. Most other implementations use the
              “jpeg_stdio_dest” from libjpeg, which can not store compressed
              pictures to memory instead of a file.
         2.: video structure from v4l2uvc.c/h, destination dstbuf and buffersize
              the dstbuf must be large enough, no error/yuvbufsize checking is done!
         3.: the dstbuf will contain the compressed data
*****************************************************************************/
int compress_yuyv_to_jpeg
(
    unsigned char* yuvbuf, 
    unsigned char *dstbuf, 
    int yuvbufsize, 
    int height, 
    int width, 
    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;
 

    
line_buffer = calloc (width * 31);
    yuyv = yuvbuf;
 
    
cinfo.err = jpeg_std_error (&jerr);
    jpeg_create_compress (&cinfo);
    /* jpeg_stdio_dest (&cinfo, file); */
    dest_buffer(&cinfo, dstbuf, yuvbufsize, &written);
 
    
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);
 
    
z = 0;
    while (cinfo.next_scanline < height)
    {
        int x;
        unsigned char *ptr = line_buffer;
 

        
for (x = 0; x < width; 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);
 
    
DEBUG_LOG(“Compress Sucess!”);
 
    
return (written);
}

 

转载请注明:胡椒小兄弟 » YUYV格式转换为JPG格式函数

喜欢 (2)or分享 (0)