I’d like to create a button that shows an image downloaded from a URL but I’m at a loss.
A Playground link isn’t possible because it lacks the required crates.
This is what I tried:
let button = Button::new();
let result = reqwest::get("https://picsum.photos/200").await.unwrap();
let bytes = result.bytes().await.unwrap().to_vec();
let pixbuf = Pixbuf::from_inline(&bytes, true).unwrap();
let image = Image::from_pixbuf(Some(&pixbuf));
button.set_image(Some(&image));
But that fails with thread 'main' panicked at 'called
Result::unwrap()on an
Err value: Error { domain: gdk-pixbuf-error-quark, code: 0, message: "Image header corrupt" }', src/main.rs:52:60
I also tried a variant like this
let result = reqwest::get("https://picsum.photos/200").await.unwrap();
let bytes = result.bytes().await.unwrap().to_vec();
let bytes = glib::Bytes::from(&bytes.to_vec());
let pixbuf = Pixbuf::from_bytes(&bytes, Colorspace::Rgb, false, 8, 200, 200, 3 * 200);
let image = Image::from_pixbuf(Some(&pixbuf));
And that fails with
GdkPixbuf-CRITICAL **: 09:26:11.165: gdk_pixbuf_new_from_bytes: assertion 'g_bytes_get_size (data) >= width * height * (has_alpha ? 4 : 3)' failed thread 'main' panicked at 'assertion failed: ::glib::types::instance_of::<Self>(ptr as *const _)',
Unfortunately, there’s almost zero documentation for any of these crates.
Does anyone have an idea on how to achieve my goal?
I’m not tied to reqwest
I did try downloading to a file first and that works:
let result = reqwest::get("https://picsum.photos/200").await.unwrap();
let mut file = File::create("pic.jpg").unwrap();
std::io::copy(&mut result.bytes().await.unwrap().as_ref(), &mut file);
This leads to a file I can open in a Browser and in Pinta which is an image editor also based on Gtk and Pixbuf.
And this also works now:
let pixbuf = Pixbuf::from_file("pic.jpg").unwrap();
let image = Image::from_pixbuf(Some(&pixbuf));
So the problem must be somewhere else. I must be using Gtk the wrong way somehow. I’d also love to use streams but I haven’t found a way to convert a Stream
to an InputStream
…
Thank you