jpeglib 코드는 번들 된 예제 코드조차도 배달 된 출력을 제공합니까?

StackOverflow https://stackoverflow.com/questions/509493

  •  21-08-2019
  •  | 
  •  

문제

나는 Ubuntu에 Intrepid에 있고 JPEGLIB62 6B-14를 사용하고 있습니다. 나는 일부 코드를 연구하고 있었는데, 그것을 실행하려고 할 때 상단에 약간의 출력이있는 검은 색 화면 만 제공했습니다. 몇 시간 동안 디버깅을 한 후에 나는 거의 JPEG베이스로 내려 갔다. 그래서 나는 예제 코드를 가져 와서 그 주위에 작은 코드를 썼고 출력은 정확히 동일했다.

나는 JPEGLIB 가이 시스템의 훨씬 더 많은 장소에서 사용되었다고 확신하며 단순히 저장소의 버전이므로 JPEGLIB 또는 Ubuntu 패키징의 버그라고 말하기를 주저합니다.

예제 코드를 아래에 넣었습니다 (대부분의 주석이 제거되었습니다). 입력 JPEG 파일은 3 개의 채널이있는 압축되지 않은 640x480 파일이므로 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);
}
도움이 되었습니까?

해결책

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

다른 팁

입력 파일을 Memmory Compressed로 읽은 다음 파일을 오게하기 전에이를 다시 압축합니다. 다시 압축하기 전에 Image_Buffer를 압축해야합니다. 또는 jpeg에서 읽는 대신 .RAW 이미지를 읽으십시오.

"입력 JPEG 파일은 압축되지 않은"이라는 의미는 무엇입니까? JPEG는 모두 압축됩니다.

코드에서 루프에서 libjpeg에 한 줄의 픽셀을 제공하고 그것을 압축하도록 요청하는 것 같습니다. 그런 식으로 작동하지 않습니다. libjpeg는 압축을 시작하려면 최소 8 행이 있어야합니다 (때로는 매개 변수에 따라 더 많은). 따라서 입력 버퍼를 제어하고 작업을 수행하지 않도록 Libjpeg를 떠나는 것이 가장 좋습니다.

CJPEG.C가 어떻게 작동하는지 읽어 보는 것이 좋습니다. 내가 생각하는 가장 쉬운 방법은 데이터를 libjpeg (예 : BMP)에서 알려진 원시 유형에 넣고 libjpeg를 사용하여 BMP 이미지를 내부 표현으로 읽고 거기에서 압축하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top