Я пытаюсь создать алгоритм, который загружает изображение JPEG с URL-адреса и сохраняет его в формате 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);
}
где контекст определяется так:
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 который я рассчитал как ширина * 3.
Где я не прав?
gdk_pixbuf_new_from_data
не поддерживает формат JPEG. Вам сначала нужно будет сохранить JPEG в файл и загрузить его с gdk_pixbuf_new_from_file
, Или создать GInputStream
вокруг ctx.data
и использовать gdk_pixbuf_new_from_stream
,
Других решений пока нет …