【问题标题】:Save an image from JPEG to PNG using libCurl and GdkPixBuff使用 libCurl 和 GdkPixBuff 将图像从 JPEG 保存到 PNG
【发布时间】:2012-10-04 13:38:01
【问题描述】:

我正在尝试构建一种算法,该算法从 URL 下载 JPEG 图像并将其以 PNG 格式保存到磁盘中。 为了实现这一点,我使用了 libCurl,用于下载,以及 GdkPixbuff 库用于其他东西(出于项目限制,我坚持使用 Gdk 库)

这里是实现数据的代码:

CURL     *curl;
GError   *error = NULL;

struct context ctx;
memset(&ctx, 0, sizeof(struct context));

curl = curl_easy_init();

if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, *file_to_download*);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDownloadedPic);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ctx);

    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
}

context 的定义如下:

struct context
{
    unsigned char *data;
    int allocation_size;
    int length;
};

writeDownloadedPic这样:

size_t writeDownloadedPic (void *buffer, size_t size, size_t nmemb, void *userp)
{
   struct context *ctx = (struct context *) userp;

   if(ctx->data ==  NULL)
   {
    ctx->allocation_size = 31014;
    if((ctx->data = (unsigned char *) malloc(ctx->allocation_size)) == NULL)
    {
        fprintf(stderr, "malloc(%d) failed\n", ctx->allocation_size);
        return -1;
    }
   }

   if(ctx->length + nmemb > ctx->allocation_size)
   {
    fprintf(stderr, "full\n");
    return -1;
   }

   memcpy(ctx->data + ctx->length, buffer, nmemb);
   ctx->length += nmemb;

   return nmemb;

}

最后我尝试以这种方式保存图像:

GdkPixbuf   *pixbuf;
pixbuf = gdk_pixbuf_new_from_data(ctx.data,
                         GDK_COLORSPACE_RGB,
                         FALSE, 8,
                         222, 310,
                         222 * 3,
                         NULL, NULL);

gdk_pixbuf_save(pixbuf, "src/pics/image.png", "png", &error, NULL);

但是,我得到的是一张带有一堆随机像素且根本没有形成的 Missy png 图像。现在,我确定了图像的尺寸、宽度和高度,但我认为我对 RowStride 做了一些处理,我计算为 width * 3。

我哪里错了?

【问题讨论】:

    标签: c++ gtk libcurl gdk gdkpixbuf


    【解决方案1】:

    gdk_pixbuf_new_from_data 不支持 JPEG 格式。您必须先将 JPEG 保存到文件中,然后使用 gdk_pixbuf_new_from_file 加载它。或者在ctx.data 周围创建一个GInputStream 并使用gdk_pixbuf_new_from_stream

    【讨论】:

    • 我喜欢 GInputStream 方法。我尝试使用 g_input_stream_read 函数来写入 CURL 的回调,但它会在第一次读取尝试后使整个应用程序崩溃!
    • 最简单的方法可能是使用gdk_pixbuf_new_from_stream 并给它一个使用g_memory_input_stream_new_from_data() 创建的内存输入流。这样 curl 下载逻辑就很简单了,而且 gdk pixbuf 可以保证加载gdk_pixbuf_new_from_stream 支持的任何类型的资源。
    猜你喜欢
    • 1970-01-01
    • 2018-06-05
    • 2017-04-16
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 2011-12-23
    相关资源
    最近更新 更多