使用OpenCV中的libjpeg将IplImage压缩为JPEG

5 compression jpeg opencv libjpeg

所以我有这个问题.我有一个IplImage,我想压缩为JPEG并用它做一些事情.我用libjpeg.我找到了很多答案"通过示例和文档阅读"等等并且做到了.并成功地为此编写了一个功能.

FILE* convert2jpeg(IplImage* frame) 
{
FILE* outstream = NULL;
outstream=malloc(frame->imageSize*frame->nChannels*sizeof(char))

unsigned char *outdata = (uchar *) frame->imageData;
struct jpeg_error_mgr jerr;
struct jpeg_compress_struct cinfo;
int row_stride;
JSAMPROW row_ptr[1];

jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outstream);

cinfo.image_width = frame->width;
cinfo.image_height = frame->height;
cinfo.input_components = frame->nChannels;
cinfo.in_color_space = JCS_RGB;

jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo, TRUE);
row_stride = frame->width * frame->nChannels;

while (cinfo.next_scanline < cinfo.image_height) {
    row_ptr[0] = &outdata[cinfo.next_scanline * row_stride];
    jpeg_write_scanlines(&cinfo, row_ptr, 1);
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

return outstream;
}
Run Code Online (Sandbox Code Playgroud)

现在这个函数直接来自示例(除了分配内存的部分,但我需要它,因为我不是写入文件),但它仍然不起作用.它死于jpeg_start_compress(&cinfo,TRUE); 部分?

有人可以帮忙吗?

tit*_*ito 7

我已经能够使用他们网站上提供的最新jpeglib找到解决方案.新方法:jpeg_mem_dest(&cinfo,outbuffer,outlen);

bool ipl2jpeg(IplImage *frame, unsigned char **outbuffer, long unsigned int *outlen) {
unsigned char *outdata = (uchar *) frame->imageData;
struct jpeg_compress_struct cinfo = {0};
struct jpeg_error_mgr jerr;
JSAMPROW row_ptr[1];
int row_stride;

*outbuffer = NULL;
*outlen = 0;

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_mem_dest(&cinfo, outbuffer, outlen);

cinfo.image_width = frame->width;
cinfo.image_height = frame->height;
cinfo.input_components = frame->nChannels;
cinfo.in_color_space = JCS_RGB;

jpeg_set_defaults(&cinfo);
jpeg_start_compress(&cinfo, TRUE);
row_stride = frame->width * frame->nChannels;

while (cinfo.next_scanline < cinfo.image_height) {
    row_ptr[0] = &outdata[cinfo.next_scanline * row_stride];
    jpeg_write_scanlines(&cinfo, row_ptr, 1);
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

return true;

}
Run Code Online (Sandbox Code Playgroud)


小智 1

在与 libJpeg 斗争了 2 天(指针、内存步进和拉扯头发)之后,我放弃了并使用了最喜欢的保存到磁盘加载到内存的方法,所以如果有人感兴趣,这里是方法:

char* convert2jpeg(IplImage* frame, int* frame_size) {

FILE* infile = NULL;
struct stat fileinfo_buf;

if (cvSaveImage(name_buf, frame) < 0) {
    printf("\nCan't save image %s", name_buf);
    return NULL;
}

if (stat(name_buf, &fileinfo_buf) < 0) {
    printf("\nPLAYER [convert2jpeg] stat");
    return NULL;
}

*frame_size = fileinfo_buf.st_size;
char* buffer = (char *) malloc(fileinfo_buf.st_size + 1);

if ((infile = fopen(name_buf, "rb")) == NULL) {
    printf("\nPLAYER [convert2jpeg] fopen %s", name_buf);
    free(buffer);
    return NULL;
}

fread(buffer, fileinfo_buf.st_size, 1, infile);
fclose(infile);

return buffer;
}
Run Code Online (Sandbox Code Playgroud)

我希望有人觉得这很有用。我希望 OpenCV 开发人员中的某个人看到这个线程并在 OpenCV 中实现直接到缓冲区 JPEG 转换,从而避免我们的痛苦和 1 次保存/加载到磁盘操作。