从 libcurl 提供的流中读取 jpeg

发布于 2024-12-26 11:13:10 字数 1268 浏览 0 评论 0原文

我有一个网络摄像机(哦惊喜)我想从中获取一些照片。一开始我只想读取一个 jpeg。由于所有通信都是通过 http 完成的,所以我使用 libcurl。所以我的代码看起来非常简单,如下所示:

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

现在我很清楚我还需要两件事。我需要声明并定义回调函数( write_test ),并且需要使用参数 CURLOPT_WRITEDATA 调用curl_easy_setopt() 并向他提供一个流。

现在的情况是我不知道该怎么做。如果我只是给他一个普通的文件流并将所有内容写入一个文件(就像它只是一些文本),它将无法工作,因为普通的文件流无法理解 jpeg。

我该怎么做?我需要像“libjpeg”这样的额外库吗?我将如何使用流?

//编辑:

好的,如上所述,我可以将单个 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));
}

这不行……?

最好的问候

托比亚斯

I have an IP Camera from which ( oh surprise ) I want to get some pictures. For the start I just want to read a single jpeg. Since all communication is done via http I'm using libcurl. So my code looks pretty simple like this:

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

Now I'm quite aware that I need two more things. I need to declare and define the callback function ( write_test ) and I need to call curl_easy_setopt() with the paramter CURLOPT_WRITEDATA and hand him a stream.

Now this is the case where I am not sure how to do this. If I just hand him a normal filestream and write all the stuff into a file (like it was just some text) it won't work since the normal filestream doesn't understand the jpeg.

How would I do this? Do I need an additional library like "libjpeg" ? And how would I work with the stream?

//edit:

Okay as mentioned I can just dump the stream of one single jpeg into a filestream. Now this actually works:

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

If I don't declare a callback function it works fine - but if I dont comment out the CURLOP_WRITEFUNCTION and declare the callback by myself I get no good results.

->

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

This doesn't work....?

Best Regards

Tobias

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

两人的回忆 2025-01-02 11:13:10

您希望将其转储到磁盘上的文件中,还是希望将其接收到内存缓冲区(或数据库或其他任何东西)?无论哪种方式,cURL 都可以帮助您。如果您希望将其保存在文件中,则可以按照您所说的使用 CURLOPT_WRITEDATA ,而无需设置任何 CURLOPT_WRITEFUNCTION 。如果您希望它位于内存缓冲区中,则必须提供 CURLOPT_WRITEDATACURLOPT_WRITEFUNCTION,后者是指向您编写的接受来自以下位置的数据的函数的指针远程服务器并将其存储在某个地方。

获得 JPEG 后,您想对它做什么?如果我理解正确的话,这似乎超出了你的问题范围,并且与 cURL 无关。 “libjpeg”确实可以帮助你。

Do you want it dumped to a file on disk, or do you want to receive it to a memory buffer (or a database, or anything else)? Either way cURL can help you. If you want it in a file then you can use CURLOPT_WRITEDATA as you've said without setting any CURLOPT_WRITEFUNCTION. If you want it in a memory buffer then you will have to supply both CURLOPT_WRITEDATA and CURLOPT_WRITEFUNCTION, the latter being a pointer to a function you have written that accepts the data coming from the remote server and stores it up somewhere.

What do you want to do with the JPEG once you get it? That seems to be outside the scope of your question if I understand it correctly, and it has nothing to do with cURL. "libjpeg" can indeed help you there.

谁的新欢旧爱 2025-01-02 11:13:10

好吧,我发现了问题所在:

出于调试目的,我实现了“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 的数据,我猜它有点损坏了内存。

Okay I found out what the problem was:

For debugging purposes I had my "write_test" function implemented like this:

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

Now unfortunately I didnt show you the part with the memcpy ( ye my fault... ). Now if I comment it out the program works. Now I didnt search the problem there since memcpy should not affect my ptr with the data. I guess it didn't but I only allocated the buffer with 50 bytes. Since I get like 2kByte everytime the write_test function is called I guess it kinda corrupted the memory.

帅哥哥的热头脑 2025-01-02 11:13:10

这是 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

This is the solution posted on libcurl's website. This function works perfectly for me with the same target as you!

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

I hope it helps! :D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文