libJPEG调用程序

本文介绍了一种基于OpenCV和LibJPEG库实现的JPEG图像压缩与解压缩的方法。通过具体的C++代码示例,展示了如何将RGB图像数据转换为JPEG格式,并能够成功还原为原始图像的过程。

//注意程序中使用了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

在Go中调用libjpeg库可以通过CGO(C语言调用Go)实现。首先,您需要安装libjpeg库和相应的C语言头文件。然后,您可以编写一个CGO文件来调用libjpeg库中的函数,在Go代码中进行调用。 以下是一个简单的示例,演示如何使用CGO调用libjpeg的解压缩函数: ```go package main //#cgo LDFLAGS: -ljpeg //#include <stdio.h> //#include <jpeglib.h> import "C" import ( "fmt" "unsafe" ) func main() { // 打开JPEG文件 file, err := C.fopen(C.CString("example.jpg"), C.CString("rb")) if err != nil { panic(err) } defer C.fclose(file) // 初始化JPEG解压缩器 var cinfo C.struct_jpeg_decompress_struct var errptr C.JSAMPARRAY C.jpeg_create_decompress(&cinfo) defer C.jpeg_destroy_decompress(&cinfo) // 设置错误处理程序 cinfo.err = C.jpeg_std_error(&cinfo.errMgr) C.jpeg_std_error(&cinfo.errMgr) C.jpeg_mem_src(&cinfo, nil, 0) C.jpeg_read_header(&cinfo, C.TRUE) // 开始解压缩JPEG图像 C.jpeg_start_decompress(&cinfo) // 读取图像数据并输出到控制台 var row_stride C.int = C.int(cinfo.output_width) * C.int(cinfo.output_components) var buffer *C.JSAMPARRAY = C.malloc(C.size_t(C.int(cinfo.output_height) * row_stride)) defer C.free(unsafe.Pointer(buffer)) for cinfo.output_scanline < cinfo.output_height { var buffer_array [1]*C.JSAMPARRAY buffer_array[0] = (*C.JSAMPARRAY)(unsafe.Pointer(uintptr(unsafe.Pointer(buffer)) + uintptr(cinfo.output_scanline) * uintptr(row_stride))) C.jpeg_read_scanlines(&cinfo, (**C.JSAMPARRAY)(unsafe.Pointer(&buffer_array[0])), 1) } fmt.Printf("Image width: %d\n", cinfo.output_width) fmt.Printf("Image height: %d\n", cinfo.output_height) fmt.Printf("Number of color components: %d\n", cinfo.out_color_components) } ``` 在这个示例中,我们使用CGO导入了libjpeg库和相应的C语言头文件。然后,我们定义了一个C结构体`struct_jpeg_decompress_struct`和一些C语言类型。接下来,我们打开JPEG文件并初始化JPEG解压缩器。然后,我们设置了错误处理程序并开始解压缩JPEG图像。最后,我们读取图像数据并输出图像的宽度、高度和颜色组件数量。 请注意,这只是一个简单的示例,实际应用可能需要更多的代码和错误处理。希望这能帮助您入门。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值