2

私はUbuntuIntrepidを使用しており、jpeglib626b-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);
}
4

3 に答える 3

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
于 2009-02-04T00:00:28.270 に答える
1

「入力JPEGファイルは非圧縮です」とはどういう意味ですか? JPEGはすべて圧縮されています。

あなたのコードでは、ループ内で1行のピクセルをlibjpegに与え、それを圧縮するように依頼しているようです。そのようには機能しません。圧縮を開始するには、libjpeg に少なくとも 8 行が必要です (パラメーターによってはそれ以上の場合もあります)。そのため、入力バッファを制御するために libjpeg をそのままにし、その仕事を行わないのが最善です。

cjpeg.c がどのように機能するかを読むことをお勧めします。私が考える最も簡単な方法は、データをlibjpeg(たとえばBMP)で知られる生のタイプに入れ、li​​bjpegを使用してBMPイメージを内部表現に読み取り、そこから圧縮することです。

于 2009-02-04T09:20:33.427 に答える
1

入力ファイルを圧縮されたメモリに読み込んでから、ファイルに書き込む前に再圧縮しています。再度圧縮する前に、image_buffer を解凍する必要があります。または、代わりに jpeg を読み込む代わりに .raw 画像を読み込みます

于 2009-02-04T00:30:03.950 に答える