Jpeglib代码提供乱码输出,甚至是捆绑的示例代码?

时间:2009-02-03 23:38:53

标签: c jpeg libjpeg

我在Ubuntu Intrepid上,我正在使用jpeglib62 6b-14。我正在研究一些代码,当我试图运行它时,它只在顶部显示了一个带有一些乱码输出的黑屏。经过几个小时的调试后,我把它归结为JPEG基础,所以我拿了示例代码,在它周围编写了一小段代码,输出完全一样。

我确信jpeglib在这个系统的更多地方使用,它只是来自存储库的版本所以我很犹豫地说这是jpeglib或Ubuntu包装中的错误。

我把下面的示例代码(大多数评论都删除了)。 输入的JPEG文件是一个未压缩的640x480文件,有3个通道,所以它应该是921600字节(它是)。输出图像是JFIF,大约9000字节。

如果你能帮我提一下,我会非常感激。

谢谢!

#include <stdio.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <setjmp.h>

int main ()
{
  // read data
  FILE *input = fopen("input.jpg", "rb");
  JSAMPLE *image_buffer = (JSAMPLE*) malloc(sizeof(JSAMPLE) * 640 * 480 * 3);
  if(input == NULL or image_buffer == NULL)
    exit(1);
  fread(image_buffer, 640 * 3, 480, input);

  // initialise jpeg library
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);

  // write to foo.jpg
  FILE *outfile = fopen("foo.jpg", "wb");
  if (outfile == NULL)
    exit(1);
  jpeg_stdio_dest(&cinfo, outfile);

  // setup library
  cinfo.image_width = 640;
  cinfo.image_height = 480;
  cinfo.input_components = 3; // 3 components (R, G, B)
  cinfo.in_color_space = JCS_RGB; // RGB
  jpeg_set_defaults(&cinfo); // set defaults

  // start compressing
  int row_stride = 640 * 3; // number of characters in a row
  JSAMPROW row_pointer[1]; // pointer to the current row data
  jpeg_start_compress(&cinfo, TRUE); // start compressing to jpeg

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

  jpeg_finish_compress(&cinfo);

  // clean up
  fclose(outfile);
  jpeg_destroy_compress(&cinfo);
}

3 个答案:

答案 0 :(得分:2)

您正在将JPEG文件读入内存(不解压缩)并将该缓冲区写出来,就好像它是未压缩的那样,这就是为什么你会得到垃圾。在将图像输入JPEG压缩器之前,需要首先解压缩图像。

换句话说,JPEG压缩器假设其输入是原始像素。

您可以使用ImageMagick将输入图像转换为原始RGB:

convert input.jpg rgb:input.raw

它的大小应该是921600字节。

编辑:当您在未压缩中声明输入 JPEG 文件时,您的问题会产生误导。无论如何,我编译了你的代码,它工作正常,正确压缩图像。如果您可以上传您正在使用的文件作为输入,则可以进一步调试。如果没有,我建议您使用使用ImageMagick从已知JPEG创建的图像测试您的程序:

convert some_image_that_is_really_a_jpg.jpg -resize 640x480! rgb:input.jpg

答案 1 :(得分:1)

您正在将输入文件读入memmory压缩文件,然后在正确归档文件之前将其重新压缩。您需要在再次压缩之前解压缩image_buffer。或者可选择性地,而不是阅读jpeg阅读.raw图像

答案 2 :(得分:1)

“输入JPEG文件是未压缩的”是什么意思? Jpegs都被压缩了。

在你的代码中,似乎在循环中你给libjpeg一行像素并要求它压缩它。它不起作用。 libjpeg必须至少有8行才能开始压缩(有时甚至更多,具体取决于参数)。所以最好让libjpeg控制输入缓冲区,而不是为它做任务。

我建议你阅读cjpeg.c如何完成它的工作。我认为最简单的方法是将数据放入libjpeg(比如BMP)已知的原始类型中,并使用libjpeg将BMP图像读入其内部表示并从那里进行压缩。