2

The main problem is that, from what I could find, there is no easy/documented way to load an image from base64 encoded image. I use the following code to encode the image to base64 (so that I wouldn't need to include all the images with the source, nor should I create temp files and delete them at exit). The image format I use is .png which is supported in Gtk3+. (from GdkPixbuf.Pixbuf.get_formats() i have ['png'] in the results. I am really confused on how to use Gtk3+ for this purpose.

import base64
image_name = 'image.png'
image_loc = 'd:\\Home\\' + image_name

with open(image_loc, 'rb') as image_file:
encoded_string = base64.b64encode(image_file.read())

print(encoded_string)

I want to use the output for example:

base64_data="""
        iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABsklEQVRYhe2XIVMCQRSAv2AwGAgEAuFmJBiMFmcMBH8AgUAgXHDMFww2gtFA
        IBicsRgNBgLBcS7yE4gEIsFgIBDO8Pa8x7FwB7cnxTfzyr637327b+/dLiTSBIbAHIgydAGMgAscyUOOpDZdAu2iyZsq4BcwAHpb9NE1xFAl
        P8s558klRFzzwQ5zejgsRxygVxBgbwiXAHtBuAaIIa7KBAgyACJgBlTKAqgBH8A0pWmIXKXYB2CbdFRM/xAA3qEBKipm8A9wCIAa8q/oUOJn
        6FTKAqgA10gZWkD9rwAugRfWm1IEfCKlKQ2ghdwrstp0vwyAuiX5HGnRMwtE1zVAfLPS6hubZ7HNgaorgFPkppxOEvcBG0AE3LoCuGZ1Zb7R
        hrGfqLGJ8h24ArhTcaYZvqHyDV0BtFWcGbLlHrJygCM1Nla+r5Cc0OcCAA3sNfaN3dtgDwDeSO5xzQIQthvRNoAlcA7yGFmowTFSmzz6jmwv
        rL6wYp0Yv7HFttKMusC3xSmP3qs4/ZxzJiTn41c85N032mEHQqQBHacWs+mFvTSQa8ldSxW4Qb7zEDntAabmWn4A0clKl9nNvDwAAAAASUVO
        RK5CYII
        """

And render the image from base64.

As a side note, on tkinter this was easily done with:

tkinter.PhotoImage(data=base64_data)

And then display the image where you needed it.

Getting back to Gtk3+, I didn't find a method of loading the image from base64. Even with GdkPixbuf.Pixbuf.new_from_data, I get a broken image. I have also tried with Gio.MemoryInputStream.new_from_bytes, but it says that the format of the image isn't supported.

Lafexlos
  • 7,618
  • 5
  • 38
  • 53
UsManyDead
  • 25
  • 5
  • HAve a look at: http://stackoverflow.com/a/20354211/956660 – Cyrbil Jan 11 '16 at 13:15
  • I have tried with Gio.MemoryInputStream, but with no success. From what I saw in that thread the issue is with opening image from url. Trying to do: inputing = Gio.MemoryInputStream.new_from_bytes(base64_image) TypeError: argument bytes: Expected GLib.Bytes, but got str / TypeError: argument bytes: Expected GLib.Bytes, but got bytes; – UsManyDead Jan 11 '16 at 15:49
  • Doing it like: byting = GLib.Bytes(base64_image) inputing = Gio.MemoryInputStream.new_from_bytes(byting) image = GdkPixbuf.Pixbuf.new_from_stream(inputing) image_show_2.set_from_pixbuf(image) i receive error: image = GdkPixbuf.Pixbuf.new_from_stream(inputing) GLib.Error: gdk-pixbuf-error-quark: Unrecognized image file format (3) – UsManyDead Jan 11 '16 at 15:50
  • Base64 decode your image first. Then give the result to `Gio.MemoryInputStream.new_from_bytes()` – Cyrbil Jan 11 '16 at 15:52
  • Thank you. It finally works. This information is so hard to find for Gtk3+. If you add this as answer I will mark it as correct answer and give rep. – UsManyDead Jan 12 '16 at 08:08

1 Answers1

3

Your data is base64 encoded, in order for Gtk3+ to use it, you must first decode it:

import base64
raw_data = base64.b64decode(data)

Then you were right with GdkPixbuf.Pixbuf.new_from_data:
(I cannot test, but I think this may work)

import base64
raw_data = base64.b64decode(data)
image = GdkPixbuf.Pixbuf.new_from_data(raw_data)
image_show_2.set_from_pixbuf(image)

Else you can do as you showed:

import base64
raw_data = base64.b64decode(data)
byting = GLib.Bytes(raw_data)
inputing = Gio.MemoryInputStream.new_from_bytes(byting)
image = GdkPixbuf.Pixbuf.new_from_data(inputing)
image_show_2.set_from_pixbuf(image)
Cyrbil
  • 6,341
  • 1
  • 24
  • 40
  • Thank you. For first you need 9 arguments (a lot of work :)) ). Second works perfectly. Unfortunately I can't vote the answer because of: "Thanks for the feedback! Once you earn a total of 15 reputation, your votes will change the publicly displayed post score." :( – UsManyDead Jan 12 '16 at 13:22
  • Also, I just found [`PixbufLoader`](http://www.pygtk.org/pygtk2reference/class-gdkpixbufloader.html) which seems to do the work `A gtk.gdk.PixbufLoader provides a way for applications to drive the process of loading an image, by letting them send the image data directly to the loader instead of having the loader read the data from a file.` – Cyrbil Jan 12 '16 at 15:38
  • I think there's a typo, in the second example it should be `Pixbuf.new_from_stream`, not data. That said, it works – phil294 Aug 17 '22 at 23:59