Re: How to store Gdk::Pixbuf pixels into std::string objects





2015-02-24 15:39 GMT+01:00 Krzesimir Nowak <qdlacz gmail com>:
2015-02-24 13:28 GMT+01:00 Glus Xof <gtglus gmail com>:
> Hi guys,
>
> I need your help...
>
> I insist that maybe it's not an specifically Gtkmm question... but you may
> know better how it's done, the library...
>
> Gdk::Pixbuf::get_pixels()... returns a guint8 (const unsigned char) pointer.
> So,
>
> 1) Which is the best way to build an std::string object containing the data
> of the buffer (the pixels)... ?
>
> Is the following well reasoned ?
>
> Glib::RefPtr<Gdk::Pixbuf> ref_orig = Gdk::Pixbuf::create_from_file
> ("./file.png");
> std::string image_pixels (reinterpret_cast<const char
> *>(ref_orig->get_pixels()), ref_orig->get_byte_length());
>
> Why std::vector(s) should be used, here ?
>

http://pastebin.com/tVBR3bGF

std::string is supposed to hold text, so storing arbitrary binary data
there is just confusing and hacky. You have to take special care about
null bytes. On the other hand, std::vector is well suited for such
task.

Thanks a lot, Krzesimir,

You have written a very beautiful example that demostrates how to use std::vector to reach the same result as the one requested by me, using std::string objects.

Another problem goes just after creating the new buffer, when this buffer is going to be set in a Gtk::Image...

Gtk:Image image;
image.set (ref_dest);

The image is not seen properly... in my case almost all pixels appear in black...

And I don't know why... while "ref_dest->save(argv[2], "png");" runs perfectly...

Glus
 
 

> ==
>
> Once an std::string object created... and from this object...
>
> 2) Which is the best way to convert it back to guint8 (const unsigned char)
> pointer, in order to pass it as first argument to
> Gdk::Pixbuf::create_from_data() ?
>
>
> I'd like to know how to realize these two steps... even if building
> std::string objects sounds a little silly or strange... I wonder... is it
> possible ?
>
> Glus
>
> 2015-02-24 11:38 GMT+01:00 Krzesimir Nowak <qdlacz gmail com>:
>>
>> 2015-02-23 23:05 GMT+01:00 Glus Xof <gtglus gmail com>:
>> >
>> >
>> > 2015-02-23 22:21 GMT+01:00 Markus Kolb <markus kolb+gtkmm tower-net de>:
>> >>
>> >> Am 2015-02-23 21:40, schrieb Glus Xof:
>> >>>
>> >>> Hi guys,
>> >>>
>> >>> Before anything, I admit that probably my question is not an
>> >>> specifically
>> >>> Gtkmm question... but nevertheless I think you may know how
>> >>> Gdk::Pixbuf
>> >>> is
>> >>> done...
>> >>>
>> >>> Having the following,
>> >>>
>> >>> Glib::RefPtr<Gdk::Pixbuf> ref_orig = Gdk::Pixbuf::create_from_file
>> >>> ("./file.png");
>> >>>
>> >>> I'm trying to temporary store (because I need so) the image data into
>> >>> a
>> >>> std::string object. It seems that get_pixels() could solve the
>> >>> problem,
>> >>> getting a pointer of type guint8.
>> >>
>> >>
>> >> Seems that gdkmm is not up-to-date here.
>> >> gdk uses a guchar*. But this shouldn't be a problem.
>> >
>> >
>> >>>
>> >>> So, I wrote as follows,
>> >>>
>> >>> std::string image_pixels (reinterpret_cast<const char
>> >>> *>(ref_orig->get_pixels()), ref_orig->get_rowstride());
>> >>
>> >>
>> >> I think this does not what you expect.
>> >>
>> >>
>> >>
>> >> https://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#gdk-pixbuf-get-rowstride
>> >>
>> >> See also the part below the description headline.
>> >>
>> >> Maybe you should use gsize Gdk::Pixbuf::get_byte_length()
>> >> because
>> >>
>> >> https://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#gdk-pixbuf-get-pixels-with-length
>> >> is missing.
>> >>
>> >> I hope it will help you.
>> >>
>> >> But think about the std::string. Big ? ;-)
>> >>
>> >
>> > According to Yann & Markus' comments, I remake my code as follows,
>> >
>> > Glib::RefPtr<Gdk::Pixbuf> ref_orig = Gdk::Pixbuf::create_from_file
>> > ("./file.png");
>> >
>> > // Glib::ustring::c_str() or data() allows me to get an std::string
>> > object...
>> >
>> > Glib::ustring image_pixels (
>> >       reinterpret_cast<const char *>(ref_orig->get_pixels()),
>> >       ref_orig->get_byte_length());
>>
>> I think you wanted to use std::string here instead of Glib::ustring.
>> Glib::ustring expects utf8 strings, not some random binary data.
>> Especially it does not like embedded zeros. The Glib::ustring
>> constructor calls utf8_byte_offset
>> (https://git.gnome.org/browse/glibmm/tree/glib/glibmm/ustring.cc#n60)
>> returns std::string::npos when it encounters embedded zero. And that
>> thing is passed to std::string constructor which throws the exception,
>> because npos is a -1 cast to size_type.
>>
>> Anyway, I'd recommend rather using std::vector instead.
>>
>> >
>> > Glib::RefPtr<Gdk::Pixbuf> ref_dest =
>> >       Gdk::Pixbuf::create_from_data (
>> >          reinterpret_cast<const guint8*>(image_pixels.data()),
>> > Gdk::COLORSPACE_RGB,
>> >          ref_orig->get_has_alpha(), ref_orig->get_bits_per_sample(),
>> >          ref_orig->get_width(), ref_orig->get_height(),
>> > ref_orig->get_rowstride());
>> >
>> > But, at runtime I get a lenght error exception,
>> >
>> > terminate called after throwing an instance of 'std::length_error'
>> >   what():  basic_string::_S_create
>> >
>> > Could help ?
>> >
>> > Glus
>> >
>> >
>> >
>> >
>> >
>> >>
>> >> _______________________________________________
>> >> gtkmm-list mailing list
>> >> gtkmm-list gnome org
>> >> https://mail.gnome.org/mailman/listinfo/gtkmm-list
>> >
>> >
>> >
>> > _______________________________________________
>> > gtkmm-list mailing list
>> > gtkmm-list gnome org
>> > https://mail.gnome.org/mailman/listinfo/gtkmm-list
>> >
>
>



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