[libjpeg]读取一张raw图(NV12格式),利用libjpeg压缩为jpg图像,并统计耗时.

面对图像较大而带宽不足的情况,往往需要对图像进行压缩,使其变小后得以方便传输。

本文使用libjpeg(非libjpeg-turbo)实现了对图像的压缩。

1.encode_by_libjpeg.h


#include <iostream>
#include <fstream>
#include <cstring>

#include <jpeglib.h>
#include <setjmp.h>

int yuv420sp_to_jpeg(const char * filename, unsigned char* pdata,int image_width,int image_height, int quality);

int read_Image_from_raw_by_iostream(const std::string filename, unsigned char **buffer);

2.encode_by_libjpeg.cpp

#include "encode_by_libjpeg.h"


int yuv420sp_to_jpeg(const char * filename,  unsigned char* pdata,int image_width,int image_height, int quality)
{   
    struct jpeg_compress_struct cinfo;  
    struct jpeg_error_mgr jerr;  
    cinfo.err = jpeg_std_error(&jerr);  
    jpeg_create_compress(&cinfo);  /*初始化*/
 
    FILE * outfile;    // target file  
    if ((outfile = fopen(filename, "wb")) == NULL) {  
        fprintf(stderr, "can't open %s\n", filename);  
        exit(1);  
    }  
    jpeg_stdio_dest(&cinfo, outfile);  /*指定输出文件*/
    
    
    /*设置压缩各项图片参数*/
    cinfo.image_width = image_width;  // image width and height, in pixels  
    cinfo.image_height = image_height;  
    cinfo.input_components = 3;    // # of color components per pixel  
    cinfo.in_color_space = JCS_YCbCr;  //colorspace of input image  
    jpeg_set_defaults(&cinfo);  
    /*设置压缩质量*/
    jpeg_set_quality(&cinfo, quality, TRUE );  
 
    //  
    //  cinfo.raw_data_in = TRUE;  
    cinfo.jpeg_color_space = JCS_YCbCr;  
    cinfo.comp_info[0].h_samp_factor = 2;  
    cinfo.comp_info[0].v_samp_factor = 2;  
    
    
    jpeg_start_compress(&cinfo, TRUE);  
 
    JSAMPROW row_pointer[1];
 
    unsigned char *yuvbuf;
    if((yuvbuf=(unsigned char *)malloc(image_width*3))!=NULL)
        memset(yuvbuf,0,image_width*3);
 
    unsigned char *ybase,*ubase;
    ybase=pdata;
    ubase=pdata+image_width*image_height;  
    int j=0;
    while (cinfo.next_scanline < cinfo.image_height) 
    {
        int idx=0;
        for(int i=0;i<image_width;i++)
        { 
            yuvbuf[idx++]=ybase[i + j * image_width];
            yuvbuf[idx++]=ubase[j/2 * image_width+(i/2)*2];
            yuvbuf[idx++]=ubase[j/2 * image_width+(i/2)*2+1];    
        }
        row_pointer[0] = yuvbuf;
        /*逐行扫描压缩写入文件*/
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
        j++;
    }

    /*完成压缩*/
    jpeg_finish_compress(&cinfo);  
    jpeg_destroy_compress(&cinfo);  
    fclose(outfile);  
    return 0;  
}

int read_Image_from_raw_by_iostream(const std::string  filename, unsigned char **buffer)
{
	   // open raw data
    
    std::ifstream fin;
    // 注意,这里要指定binary读取模式
    fin.open(filename,  std::ios::binary);
    if (!fin) {
        std::cerr << "open failed: " << filename << std::endl;
    }
	// seek函数会把标记移动到输入流的结尾
    fin.seekg(0, fin.end);
    // tell会告知整个输入流(从开头到标记)的字节数量
    int length = fin.tellg();
   	// 再把标记移动到流的开始位置
    fin.seekg(0, fin.beg);
    //std::cout << "file length: " << length << std::endl;
    
    // load buffer
    char* temp_buf = new char [length];
    // read函数读取(拷贝)流中的length各字节到buffer
    fin.read(temp_buf, length);
	
	*buffer=reinterpret_cast<u_char *>(temp_buf);
    return 0;

}

3.main.cpp

#include "encode_by_libjpeg.h"
#include <iostream>

#include <algorithm>
#include <chrono>


struct Rawimage_t {
	size_t input_w, input_h;
	unsigned char *yuv420sp;
};


int main()
{
    
    Rawimage_t image;

    int yuv_size=0;
    int input_width=3840 ;
    int input_height=2176;
  
	read_Image_from_raw_by_iostream(raw[i-4], &image.yuv420sp);

	auto start = std::chrono::high_resolution_clock::now();
    
    yuv420sp_to_jpeg("output.jpg",image.yuv420sp,input_width,input_height, 60);
	
    auto stop = std::chrono::high_resolution_clock::now();
   	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
	std::cout << "Time taken: " << duration.count() /1000.0<< " ms" << std::endl;	
	
    /* Free image memory */
	free(image.yuv420sp);
			
	}
	
    return 0;
}

4.Makefile

a : main.cpp encode_by_libjpeg.cpp
	g++ main.cpp encode_by_libjpeg.cpp  -I/opt/libjpeg-turbo/include -L/opt/libjpeg-turbo/lib64 -ljpeg   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值