2010-12-30 21 views
21

私は、ファイルに書き込むためのlibjpegを使用してこの機能を発見した:私は実際に時間を節約するために、それをファイルに保存せず、単にメモリバッファにJPEG圧縮された画像を作成する必要がありますでしょう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; 
} 

を。誰かが私にそれを行う方法の例を教えてもらえますか?

私はしばらくWebを検索していましたが、もしあれば、やっぱり難しい例もあります。

答えて

15

独自の宛先マネージャを簡単に定義することができます。 jpeg_compress_structは、バッファへのポインタを含むjpeg_destination_mgrへのポインタ、バッファに残された空間の数、および機能への3つのポインターが含まれています

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

あなたが作る前に、関数ポインタに記入する必要がありますjpegライブラリへの最初の呼び出しを行い、それらの関数がバッファを処理できるようにします。考えられる最大の出力よりも大きなバッファを作成すると、これは簡単になります。 init_destinationはバッファポインタを数えてカウントし、empty_output_bufferterm_destinationは何もしません。

ここではいくつかのサンプルコードです:

std::vector<JOCTET> 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; 
+0

私は、これらの関数ポインタが 'jpeg_stdio_dest'に影響すると思いますか? –

+0

@Ben Voigt、 'jpeg_stdio_dest'へのソースを見ています。構造体を割り当てて 'cinfo-> dest'にセットし、ポインタを設定します。私は自分のサンプルコードが 'jpeg_destination_mgr'構造体を作成しないので少し不完全かもしれないと思っていますが、後でそれを見ていきます。 –

+0

もちろん、ああ。関数ポインタの直後に、グローバル変数は必要ありません(自分自身のデータ( 'std :: vector')を格納することができます。](http://blogs.msdn.com/b/oldnewthing/archive/2010/12/20/ 10107027.aspx)。 –

0

FILEのようなオブジェクトをjpeg_stdio_dest()に渡すだけです。

9

jdatasrc.cで定義された定義済みの機能jpeg_mem_srcがありますが。最も単純な使用例:

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 

バッファの割り当てを忘れないでください。

+0

私の' jdatasrc.c'(libjpeg-6b)にはありません。 –

+2

libjpegの最新の安定版は9です。ここで入手できます。http://www.ijg.org/files/jpegsr9.zip jpeg_mem_srcが含まれています。 – dmitriykovalev

+0

memバッファを空けて呼び出すか削除しますか?私はdelete []を呼び出し、valgrindは私に不一致の削除警告を与えました。フリー()を使用し、警告が消えました。 – shehzan

3

私はマークのソリューションを試してみました、それは

cinfo->dest->term_destination = &my_term_destination; 

を実行したときに私のプラットフォーム上で、それは常にセグメンテーションFALUTエラーを与え、私は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です。

1
unsigned char ***image_ptr  
unsigned char* ptr; 
unsigned char** image_buf; 

for(int i=0;i<h;i++){ 
image_buf[i] = new unsigned char[w*o]; 
} 

ptr = image_buf[0]; 

    while (info.output_scanline < info.image_height) { 

    jpeg_read_scanlines(&info,&ptr,1); 

    ptr = image_buf[c]; 

    c++; 


    } 

    *image_ptr = image_buf; 

これはすべての必要があります。

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); 



           } 

これですべてを書く必要があります。

+8

**警告** - あなたの記事におどかしい言葉を使わないでください。私はあなたのためにそれを削除しました。他のユーザーがあなたの投稿に「失礼や虐待」と警告している可能性があります。 [Be Nice](http://superuser.com/help/be-nice)を読んでください: "下品な言葉や性的に示唆的なものは避けてください" – DavidPostill

関連する問題