2012-01-10 16 views
0

私はIPカメラを持っています(ああ、驚いて)写真を撮りたいです。開始のために私はちょうど単一のjpegを読みたいと思う。すべての通信はhttp経由で行われるので、libcurlを使用しています。ですから、私のコードは次のようにとても簡単に見えます。libcurlが提供するストリームからjpegを読み込みます。

// Initialize some stuff 
CURL * curl; 
curl = curl_easy_init(); 
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.147/cgi-bin/mjpeg?mode=single"); curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, write_test); 

私はもう2つのことが必要であることをよく知っています。コールバック関数(write_test)を宣言して定義する必要があり、パラメータCURLOPT_WRITEDATAを指定してcurl_easy_setopt()を呼び出してストリームを渡す必要があります。

ここで私はこれを行う方法がわかりません。通常のファイルストリームを手渡してファイルに書き込むと(通常のテキストのように)、通常のファイルストリームはjpegを理解できないため動作しません。

どうすればよいですか? "libjpeg"のような追加のライブラリが必要ですか?そして私はその川でどのように働くでしょうか?

//編集:私はだけファイルストリームに1枚のJPEGのストリームをダンプすることができます述べたように

わかりました。さて、これは実際に動作します:

FILE* pFile = fopen("/home/username/test.jpeg","w"); 
curl = curl_easy_init(); 
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.147/cgi-bin/mjpeg?mode=single"); 
//curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, write_test); 
curl_easy_setopt(curl,CURLOPT_WRITEDATA, pFile); 
curl_easy_perform(curl); 

私はコールバック関数を宣言しない場合、それは正常に動作します - しかし、私はCURLOP_WRITEFUNCTIONをコメントアウトいけないと自分でコールバックを宣言した場合、私は良い結果を得るません。

- >

size_t write_test(void *ptr, size_t size, size_t nmeb, void *stream) 
{ 
    return fwrite(ptr,size,nmeb,static_cast<FILE*>(stream)); 
} 

これは....動作しませんか?

よろしく

トビアス

+1

"通常のファイルストリームはjpegを理解できないため動作しません。"何を理解する必要がありますか?拡張子が.jpgのバイナリモードでファイルを書き出すと、それは機能しません。あるいは、JFIFヘッダなしでデータを取得していますか?またはファイルを何らかの方法で最初に処理したいと思っていますか?それとも、個々のイメージにカットするために必要な連続的な流れを与えるか、それとも何か他のものを与えるのですか? – Rup

+0

オハイオ州の男、時々私は早朝にこれを動作させるべきではないと感じています - 私が(私がただ一つの写真を撮ると)すべてのストリームをファイルにダンプすることができます。しかし、私は別のことに気付かなかった(上記の質問でそれを指定する) – Toby

+0

write_testコールバック関数は、受け取ったものと全く同じパラメータで 'fwrite'を呼び出す以外に何もしない限り、私には似ています。 'write_test'がC++関数であり、何らかの形でC関数(つまり' extern "C" {} 'ブロック)として宣言する必要があるからでしょうか?私はC++を知らない。 – Celada

答えて

1

私は問題が何であったかがわかったわかりました:私はこのように実装私の「write_test」機能を持っていたデバッグの目的のために

size_t write_test(void *ptr, size_t size, size_t nmeb, void *stream) 
{ 
    memcpy(buffer,ptr,size*nmeb); 
    size_t no; 

    no = fwrite(ptr,size,nmeb,static_cast<FILE*>(stream)); 
    printf("no: %d\tsize: %d\tnmeb: %d\n",no,size,nmeb); 
    return no; 
} 

は今、残念ながら私は(memcpyをとあなたの一部を示していませんでしあなたは私のせいです...)。今私はそれをコメントアウトすると、プログラムが動作します。今私はmemcpyがデータで自分のptrに影響を与えてはならないので、そこで問題を検索しませんでした。私はそれがなかったと思うしかし、私は50バイトでバッファを割り当てた。 write_test関数が呼び出されるたびに2kByteのようになるので、メモリがちょっと壊れていると思います。

1

あなたはそれがディスク上のファイルにダンプしたいか、またはあなたはメモリバッファ(またはデータベース、または何か他)にそれを受信したいですか?どちらの方法でもcURLはあなたを助けることができます。あなたがそれをファイルに入れたい場合は、CURLOPT_WRITEFUNCTIONを設定せずに言ったようにCURLOPT_WRITEDATAを使うことができます。メモリバッファに入れたい場合は、CURLOPT_WRITEDATACURLOPT_WRITEFUNCTIONの両方を指定する必要があります。後者は、リモートサーバからのデータを受け取り、どこかに格納する関数へのポインタです。

あなたは何をしますか?を入手したら、それを入手しますか?それが正しく理解されていれば、それはあなたの質問の範囲外であると思われ、それはcURLとは何の関係もありません。 "libjpeg"は本当にあなたを助けることができます。

0

これはlibcurlのウェブサイトに掲載されているソリューションです。この機能は、あなたと同じターゲットで私にとって完璧に機能します!

struct MemoryStruct { 
    char *memory; 
    size_t size; 
}; 


size_t MailServer::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) 
{ 
    size_t realsize = size * nmemb; 
    struct MemoryStruct *mem = (struct MemoryStruct *)userp; 

    mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1); 
    if(mem->memory == NULL) { 
     /* out of memory! */ 
     printf("not enough memory (realloc returned NULL)\n"); 
     return 0; 
    } 

    memcpy(&(mem->memory[mem->size]), contents, realsize); 
    mem->size += realsize; 
    mem->memory[mem->size] = 0; 

    return realsize; 
} 

私はそれが助けてくれることを願っています! :D

関連する問題