//注意程序中使用了OPENCV的函数 // MYTEST_LIBJPEG.cpp : Defines the entry point for the console application. // //参考:以下网址的内容 // http://www.cppblog.com/socketref/archive/2006/03/02/3623.html //http://www.vckbase.net/code/listcode.asp?mclsid=7 #i nclude "stdafx.h" #i nclude "memory.h" #i nclude "string.h" extern "C" { #i nclude "E:/program/GnuWin32/include/jpeglib.h" } #pragma comment(lib, "E:/program/GnuWin32/lib/jpeg.lib") /// //openCV头文件 #i nclude "cv.h" #i nclude "highgui.h" / #define image_w 283 #define image_h 212 bool JpegCompress(int w,int h,const char * rgb_data,int rgb_size, char * jpeg_data,int *jpeg_size); bool JpegUnCompress(const char * jpeg_data,int jpeg_size, char *rgb_data,int rgb_size,int w,int h); //============================================================== //示例 int main(int argc, char* argv[]) { printf("Hello World!/n"); int image_size = image_w * image_h * 3; //图片大小 int jpeg_size = 0; IplImage* pImg; //声明IplImage指针 pImg = cvLoadImage( "test.bmp", -1); IplImage* = 0; CvSize n_size = cvSize(image_w, image_h); = cvCreateImageHeader(n_size, IPL_DEPTH_8U, 3); //创建图像头 cvNamedWindow( "Image", 1 );//创建窗口 cvNamedWindow( "Image2", 1 );//创建窗口 cvShowImage( "Image", pImg );//显示图像 char* jpeg_data = (char*)malloc(image_size); char* bmp_data = (char*)malloc(image_size); if(!JpegCompress(image_w, image_h, (const char *)pImg->imageData, image_size, jpeg_data, &jpeg_size)) { printf("compress error!"); } printf("size of bmp = %ld /n", image_size); printf("size of jpeg = %ld /n", jpeg_size); printf("compressed = %f /n", (double)jpeg_size/image_size); if(!JpegUnCompress((const char *)jpeg_data, jpeg_size, bmp_data, image_size, image_w, image_h)) { printf("uncompress error!"); } ->imageData = bmp_data; cvShowImage( "Image2", );//显示图像 cvWaitKey(0); //等待按键 free(jpeg_data); free(bmp_data); cvDestroyWindow( "Image" );//销毁窗口 cvDestroyWindow( "Image2" ); cvReleaseImage( &pImg ); //释放图像 cvReleaseImageHeader(&); //释放中间转换图像头占用的内存 return 0; } //=============================================================== void JpegInitDestination(j_compress_ptr cinfo) { } static boolean JpegEmptyOutputBuffer(j_compress_ptr cinfo) { return TRUE; } static void JpegTermDestination(j_compress_ptr cinfo) { // jpegDstDataLen = jpegDstBufferLen - jpegDstManager.free_in_buffer; } //============================================================== //Raw Rgb Data converted to Jpeg data //w图像宽 //h图像高 //rgb_data: RGB数据开始指针 //rgb_size: 没有使用 //jpeg_data: 压缩完的JPEG数据指针 //jpeg_size: 压缩完的数据个数 //说明:只可压RGB888格式的纯位图数据 bool JpegCompress(int w,int h,const char * rgb_data,int rgb_size, char * jpeg_data,int *jpeg_size) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_destination_mgr jpegDstManager; int ret; //unsigned char *srcBuf = new unsigned char[w * 3]; JSAMPROW rowPointer[1]; //rowPointer[0] = (JSAMPROW)srcBuf; int left_size; left_size = *jpeg_size; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; // 1,表示灰度图, 如果是彩色位图,则为3 cinfo.in_color_space = JCS_RGB; cinfo.raw_data_in = true; jpeg_set_defaults(&cinfo); cinfo.dest = &jpegDstManager; jpegDstManager.next_output_byte = (unsigned char*)jpeg_data; jpegDstManager.free_in_buffer = left_size; jpegDstManager.init_destination = JpegInitDestination; jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer; jpegDstManager.term_destination = JpegTermDestination; jpeg_set_quality(&cinfo, 50, TRUE); //压缩质量 jpeg_start_compress(&cinfo, TRUE); for(int y=0; y< h; y++) { rowPointer[0] = (unsigned char*)(rgb_data + y*w*3); ret = jpeg_write_scanlines(&cinfo, rowPointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); *jpeg_size = left_size - jpegDstManager.free_in_buffer; return true; } //================================================================= void JpegInitSource(j_decompress_ptr cinfo) { } //================================================================ boolean JpegFillInputBuffer(j_decompress_ptr cinfo) { /* jpegError = true; jpegSrcManager.bytes_in_buffer = jpegBufferLen; jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; */ return TRUE; } //================================================================== void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes) {/* 87 if (num_bytes < 0 || (size_t)num_bytes > jpegSrcManager.bytes_in_buffer) { 88 jpegError = true; 89 jpegSrcManager.bytes_in_buffer = jpegBufferLen; 90 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr; 91 } else { 92 jpegSrcManager.next_input_byte += (size_t) num_bytes; 93 jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes; 94 }*/ } //=============================================================== void JpegTermSource(j_decompress_ptr cinfo) { /* No work necessary here. */ } //============================================================ //Jpeg data Raw converted to Rgb Data //w图像宽 //h图像高 //rgb_data: RGB数据开始指针 //rgb_size: 没有使用 //jpeg_data: 压缩完的JPEG数据指针 //jpeg_size: 压缩完的数据个数 //说明:只可解压RGB888格式的纯位图数据 bool JpegUnCompress(const char * jpeg_data,int jpeg_size, char *rgb_data,int rgb_size,int w,int h) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_source_mgr jpegSrcManager; int ret; JSAMPROW rowPointer[1]; cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpegSrcManager.init_source = JpegInitSource; jpegSrcManager.fill_input_buffer = JpegFillInputBuffer; jpegSrcManager.skip_input_data = JpegSkipInputData; jpegSrcManager.resync_to_restart = jpeg_resync_to_restart; jpegSrcManager.term_source = JpegTermSource; jpegSrcManager.next_input_byte = (unsigned char*)jpeg_data; jpegSrcManager.bytes_in_buffer = jpeg_size; cinfo.src = &jpegSrcManager; jpeg_read_header(&cinfo, TRUE); cinfo.out_color_space = JCS_RGB; jpeg_start_decompress(&cinfo); if( cinfo.output_width != (unsigned int)w || cinfo.output_height != (unsigned int)h) { jpeg_destroy_decompress(&cinfo); return false; } for (int dy = 0; cinfo.output_scanline < cinfo.output_height; dy++) { rowPointer[0] = (unsigned char *)(rgb_data + w*dy*3); ret = jpeg_read_scanlines(&cinfo, rowPointer, 1); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return true; } //
zz:http://www.roboticfan.com/blog/user_2005/5669/archives/2008/2008111249.shtml