How to do Image manipulation from binary

Hi :slightly_smiling_face:

I’m trying to use AdwAvatar to add pictures to my app from binary data I get from an HTTP request… But I had no luck.

I probably didn’t understood correctly. So here’s my current understanding;

  1. AdwAvatar use a Paintable to get the image with set_custom_image.
  2. Gdk.Paintable.snapshot use Snapshot to create Paintable object.
  3. snapshot.append_texture allow you to put a picture in a snapshot.
  4. You need a Gdk.Texture and a Graphene.Rect to use “snapshot.append_texture”
  5. You can use Gdk.Texture.new_from_bytes to create a texture from your Binary
  6. You need to convert your Bytes to GBytes with GLib.Bytes.new to use Gdk.Texture.new_from_bytes.

But so far, it doesn’t work. I don’t get errors; I just get no images on AdwAvatar.

Here’s my commented code;

# Get image binary
imageData = self.runGetQuery("/ocs/v2.php/apps/spreed/api/v1/room/" + child.find('token').text + "/avatar", 1)

# create GBytes from Bytes
avatarGBytes = GLib.Bytes.new(imageData)

# Create a texture from it
avatartexture = Gdk.Texture.new_from_bytes(avatarGBytes)

# Create a Snapshot
snapshot = Gtk.Snapshot.new()

# Create a Rect
avatarRect = Graphene.Rect.alloc()
avatarRect.init(0, 0, 64, 64)

# Combine texture and Rect to populate the Snapshot
snapshot.append_texture(avatartexture, avatarRect)

# Create a new Paint and add it the snapshot
pt = Gdk.Paintable.new_empty(64, 64)
pt.snapshot(snapshot, 64, 64)

# create the avatar Object
avatar = Adw.Avatar()

# Finaly; Set the image.
avatar.set_custom_image(pt)

Did I took the right path ? Could someone give some advices ?

Tank you

Texture is already a paintable, you can just set it as a custom image as is.

And no, you cannot just create a paintable like this. What happened was that you drew the paintable to the snapshot, not the other way around.

Oh ! That’s way more simple. It work ! Yay !

Thank you again :slightly_smiling_face:

Please make sure that you’re not making blocking requests on the main thread. If you’re using Soup (which, you should be!), use session.send_and_read_async(), which gives you the Bytes directly.

1 Like

@bugaevc Yep I use Soup ^^’ And this was for the “POC”; Now I put all the functions doing the async request into a GLib.idle_add and then they all init and respond without making the app lag :slightly_smiling_face: I kind of use the Idle thing as a “waiting room” for the task to be done. It may not be great ^^’