看着libjpeg的文档说明,写了个例子,备忘。
extern "C" { #include "jpeglib.h" } class Sbuffer { public: Sbuffer(); ~Sbuffer(); bool SetSize(int size); inline unsigned char* GetBuffer(){ return buffer_; } private: int size_; unsigned char* buffer_; }; Sbuffer::Sbuffer():size_(0), buffer_(NULL){} Sbuffer::~Sbuffer() { if(buffer_){ delete[] buffer_; buffer_ = NULL; size_ = 0; } } bool Sbuffer::SetSize(int size) { if(size > size_){ if(buffer_){ delete[] buffer_; buffer_ = NULL; } size_ = 0; buffer_ = new unsigned char[size]; if(NULL == buffer_){ TRACE("Sbuffer::SetSize new failed"); return false; } size_ = size; return true; } return true; } static int reduce_jpeg(const char* filename) { int image_new_width = 0; int image_new_height = 0; int image_new_components = 0; J_COLOR_SPACE image_new_colorspace = JCS_UNKNOWN; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); FILE* infile; if((infile = fopen(filename, "rb")) == NULL) { return -1; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); //get jpeg info jpeg_read_header(&cinfo, TRUE); //set parameters cinfo.scale_num = 1; cinfo.scale_denom = 2;//reduce image 1/2 jpeg_start_decompress(&cinfo); //restore image_new_width = cinfo.output_width; image_new_height = cinfo.output_height; image_new_components = cinfo.output_components; image_new_colorspace = cinfo.out_color_space; int buffer_len = cinfo.output_width * cinfo.output_components * cinfo.output_height; static Sbuffer s_buffer; s_buffer.SetSize(buffer_len * sizeof(JSAMPLE)); JSAMPLE* image_buffer = static_cast<JSAMPLE*>(s_buffer.GetBuffer()); if(NULL == image_buffer){ fclose(infile); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return -1; } memset(image_buffer, 0, buffer_len*sizeof(JSAMPLE)); int row_stride = cinfo.output_width * cinfo.output_components; JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); JSAMPLE* image_buffer_cur_pos = image_buffer; while(cinfo.output_scanline < cinfo.output_height){ jpeg_read_scanlines(&cinfo, buffer , 1); memcpy((void*)image_buffer_cur_pos, (const void*)buffer[0], row_stride*sizeof(JSAMPLE) ); image_buffer_cur_pos += row_stride; } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(infile); /////////////////////////////////////////// //save struct jpeg_compress_struct cinfo_save; struct jpeg_error_mgr jerr_save; cinfo_save.err = jpeg_std_error(&jerr_save); FILE* outfile = fopen(filename, "wb"); if(NULL == outfile){ return -1; } jpeg_create_compress(&cinfo_save); jpeg_stdio_dest(&cinfo_save, outfile); cinfo_save.image_width = image_new_width; cinfo_save.image_height = image_new_height; cinfo_save.input_components = image_new_components; cinfo_save.in_color_space = image_new_colorspace; jpeg_set_defaults(&cinfo_save); jpeg_set_quality(&cinfo_save, 80, true); jpeg_start_compress(&cinfo_save, TRUE); JSAMPROW row_pointer[1]; row_stride = cinfo_save.image_width * cinfo_save.input_components; while(cinfo_save.next_scanline < cinfo_save.image_height){ row_pointer[0] = &image_buffer[ cinfo_save.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo_save, row_pointer, 1); } jpeg_finish_compress(&cinfo_save); jpeg_destroy_compress(&cinfo_save); fclose(outfile); image_buffer = NULL; return 1; }