jpeg to bmp with pixbuf; gtk cairo imagemagick libcurl



I've used ImageMagick http://www.imagemagick.org/script/index.php to bring jpegs into cairo surfaces which is similar. They have an api that lets you decode a file to a memory buffer directly. Pay close attention to the different pixel formats. Here is some code that will embarrass me. I pulled this out of my personal demos/tests/examples/scratch ideas directory. This is over a year old, and I'm not even going look that closely at it because I have huge headache. :) Anyway, I think this will bring up a gtk window, use curl to pull a image from a url, then use image magick to decode it, then display it (un resized). The noteworthy aspect is that a temporary file is never used. You might could adapt this. PNGs are used, but I the BlobToImage() will auto detect any supported format.


#include <gtk/gtk.h>
#include <stdio.h>
#include <magick/api.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

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

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

if(ctx->data ==  NULL)
{
 ctx->allocation_size =  10 * 1024;
 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;
fprintf(stderr, "got here size=%d nmemb=%d length=%d\n", size, nmemb, ctx->length);

return nmemb;
}

unsigned char *get_it(int *length)
{
CURL *handle;
struct context ctx;

if(curl_global_init(CURL_GLOBAL_ALL))
{
 printf("curl_global_init() fialed\n");
 return NULL;
}

if((handle = curl_easy_init()) == NULL)
{
 printf("curl_easy_init() fialed\n");
 curl_global_cleanup();
 return NULL;
}

curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, handle_curl_data);

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

curl_easy_setopt(handle, CURLOPT_WRITEDATA, &ctx);

curl_easy_setopt(handle, CURLOPT_URL, "http://us.maps2.yimg.com/us.png.maps.yimg.com/png?v=3.52&t=m&x=1&y=0&z=17";);

curl_easy_perform(handle);

curl_easy_cleanup(handle);
curl_global_cleanup();

*length = ctx.length;
return ctx.data;
}


cairo_surface_t *loadimage(void)
{
cairo_surface_t *surface;
ExceptionInfo exception;
Image *image;
ImageInfo *image_info;
unsigned char *decoded_png, *encoded_png;
PixelPacket *pixels;
int x, y, length;

encoded_png = get_it(&length);

InitializeMagick(NULL);
GetExceptionInfo(&exception);
image_info = CloneImageInfo((ImageInfo *) NULL);

image = BlobToImage(image_info, encoded_png, length, &exception);

pixels =
AcquireImagePixels(image, 0, 0, image->magick_columns,
                   image->magick_rows, &exception);

for(y = 0; y < image->magick_rows; y++)
{
 for(x = 0; x < image->magick_columns; x++)
 {
/*   printf(" {%d,%d,%d,%d}\n",
  pixels[(y * image->magick_columns) + x].blue,
  pixels[(y * image->magick_columns) + x].green,
  pixels[(y * image->magick_columns) + x].red,
  pixels[(y * image->magick_columns) + x].opacity);*/
pixels[(y * image->magick_columns) + x].opacity = 255;
 }
}

decoded_png = (unsigned char *) pixels;

surface =
cairo_image_surface_create_for_data(decoded_png, CAIRO_FORMAT_ARGB32,
                                    image->magick_columns,
                                    image->magick_rows,
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, image->magick_columns));

//DestroyMagick();
return surface;
}

struct test_ctx
{
cairo_t *cr;
GtkWidget *widget;
};

int draw(struct test_ctx *ctx)
{
static cairo_surface_t *image = NULL;

if(image == NULL)
 image = loadimage();

cairo_set_source_surface(ctx->cr, image, 0, 0);

cairo_paint(ctx->cr);

return 0;
}

static gboolean drawing_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
struct test_ctx *ctx = (struct test_ctx *) data;

ctx->cr = gdk_cairo_create(widget->window);

/* set a clip region for the expose event */
cairo_rectangle(ctx->cr, event->area.x, event->area.y,
                event->area.width, event->area.height);
cairo_clip(ctx->cr);
draw(ctx);

cairo_destroy(ctx->cr);
ctx->cr = NULL;

return FALSE;
}

int main(int argc, char **argv)
{
GtkWidget *window;
struct test_ctx real_ctx, *ctx = &real_ctx;

ctx->cr = NULL;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

ctx->widget = gtk_drawing_area_new();

gtk_container_add (GTK_CONTAINER (window), ctx->widget);

g_signal_connect(window, "destroy",
                 G_CALLBACK (gtk_main_quit), NULL);

g_signal_connect(G_OBJECT(ctx->widget), "expose_event", G_CALLBACK(drawing_area_expose), (gpointer) ctx);

gtk_widget_show_all(window);
gtk_main();

return 0;
}



Date: Wed, 28 Jan 2009 20:36:09 -0200
From: frederico schardong <frede sch gmail com>
Subject: jpeg to bmp with pixbuf

Hello,

How I can transform a jpeg imagem to bitmap format using pixbuf?

It's possible??

Thank you!





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]