使用libjpeg写入内存缓冲区而不是文件?

我发现这个函数使用libjpeg写入文件:

int write_jpeg_file( char *filename ) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; /* this is a pointer to one row of image data */ JSAMPROW row_pointer[1]; FILE *outfile = fopen( filename, "wb" ); if ( !outfile ) { printf("Error opening output jpeg file %s\n!", filename ); return -1; } cinfo.err = jpeg_std_error( &jerr ); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, outfile); /* Setting the parameters of the output file here */ cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = bytes_per_pixel; cinfo.in_color_space = color_space; /* default compression parameters, we shouldn't be worried about these */ jpeg_set_defaults( &cinfo ); /* Now do the compression .. */ jpeg_start_compress( &cinfo, TRUE ); /* like reading a file, this time write one row at a time */ while( cinfo.next_scanline < cinfo.image_height ) { row_pointer[0] = &raw_image[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; jpeg_write_scanlines( &cinfo, row_pointer, 1 ); } /* similar to read file, clean up after we're done compressing */ jpeg_finish_compress( &cinfo ); jpeg_destroy_compress( &cinfo ); fclose( outfile ); /* success code is 1! */ return 1; } 

我实际上需要将jpeg压缩图像写入内存缓冲区,而不将其保存到文件中,以节省时间。 有人可以举个例子来说明怎么做吗?

我一直在网上搜索一段时间,但如果有任何例子也难以获得,那么文档很少见。

您可以非常轻松地定义自己的目标管理器。 jpeg_compress_struct包含一个指向jpeg_compress_struct的指针,该指针包含指向缓冲区的指针,缓冲区中剩余的空间计数以及指向函数的3个指针:

 init_destination (j_compress_ptr cinfo) empty_output_buffer (j_compress_ptr cinfo) term_destination (j_compress_ptr cinfo) 

在第一次调用jpeg库之前,需要填写函数指针,然后让这些函数处理缓冲区。 如果您创建的缓冲区大于您期望的最大可能输出,则这变得微不足道; init_destination只填充缓冲区指针和count,而empty_output_bufferterm_destination什么都不做。

这是一些示例代码:

 std::vector my_buffer; #define BLOCK_SIZE 16384 void my_init_destination(j_compress_ptr cinfo) { my_buffer.resize(BLOCK_SIZE); cinfo->dest->next_output_byte = &my_buffer[0]; cinfo->dest->free_in_buffer = my_buffer.size(); } boolean my_empty_output_buffer(j_compress_ptr cinfo) { size_t oldsize = my_buffer.size(); my_buffer.resize(oldsize + BLOCK_SIZE); cinfo->dest->next_output_byte = &my_buffer[oldsize]; cinfo->dest->free_in_buffer = my_buffer.size() - oldsize; return true; } void my_term_destination(j_compress_ptr cinfo) { my_buffer.resize(my_buffer.size() - cinfo->dest->free_in_buffer); } cinfo->dest->init_destination = &my_init_destination; cinfo->dest->empty_output_buffer = &my_empty_output_buffer; cinfo->dest->term_destination = &my_term_destination; 

jpeg_mem_src定义了一个预定义函数jdatasrc.c 。 最简单的用法示例:

 unsigned char *mem = NULL; unsigned long mem_size = 0; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_mem_dest(&cinfo, &mem, &mem_size); // do compression // use mem buffer 

不要忘记释放缓冲区。

我已经尝试了Mark的解决方案,并且在我的平台上它总是在执行时给出SEGMENTATION FALUT错误

 cinfo->dest->term_destination = &my_term_destination; 

我转向jpeglib源代码(jdatadst.c)并发现:

 jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer, unsigned long * outsize) 

就在方法jpeg_stdio_dest()的下方,我只是通过填写缓冲区的地址(char *)和缓冲区大小的地址(int)来尝试它。 目标管理器自动为缓冲区分配内存,程序需要在使用后释放内存。

它成功运行在我的平台Beaglebone Black上,预装了Angstrom Linux。 我的libjpeg版本是8d。

您需要做的就是将类似FILE的对象传递给jpeg_stdio_dest()

 unsigned char ***image_ptr unsigned char* ptr; unsigned char** image_buf; for(int i=0;i 

这就是你需要阅读的全部内容。

 JSAMPROW row_pointer; while (info.next_scanline < info.image_height) { row_pointer = &image_buf[info.next_scanline][0]; (void) jpeg_write_scanlines(&info, &row_pointer, 1); } 

这就是你需要写的全部内容。