[C] Manipulacija slike in dostop do pixlov v gtk

Jaz imam nov problem. Za seminarsko delam nek program, ki bo obdeloval sliko, ter jo prikazal na zaslonu!

Naredil sem GUI v glade 3. V GUI imam widget GtkImage. V image naložim sliko brez problema, sedaj me pa zanima:
1. kako dostopati do pixlov? (get in put)
2. kako prikazati v widget GtkImage dve sliki, s tem da ima vrhnja slika določen transparency(prosojnost)?

1. Vem, da imam na voljo več možnih "formatov": pixbuf, gdk_image, ... Za pixbuf vem, da so problemi če slika ni 8bitna(8bit za posamezen kanal), dostop do pixlov pa naj bi bil takšen:
pixel_x_y = (int)gdk_pixbuf_get_pixels(pixbuf)[y*rowstride+(x*3)+color]
Tako, da me zanima, kaj naj uporabim (pixbuf, gdk_image, ...) in kakšni so dostopi do pixlov?

2. nimam pojma

Že od včeraj googlam vendar rešitve nisem uspel najdi, tako da upam na vašo pomoč!!

Vnaprej hvala za vaše odgovore!

Lp: 1GOR

Komentarji

  • napsy Član Ubuntu.si
    1.

    gtk_image_get_pixbuf() torej dobiš GdkPixbuf, nato pa klic gdk_pixbuf_get_pixels() vrne guchar *, kjer lahko dostopaš do posameznih pikslov.

    guchar *piksel = data + (gdk_pixbuf_get_rowstride(pixbuf) * y + gdk_pixbuf_get_n_channels (pixbuf) * x);
    Funkcija gdk_pixbuf_get_rowstride() vrne število bajtov v eni vrstici slike. Funkcija gdk_pixbuf_get_n_channels() ti vrne število kanalov v enem pikslu.

    2.
    Alfa kanal je četrti bajt v pikslu, če imaš RGBA pixmap. Torej s piksel[3] lahko določaš prosojnost. Mešanje ene in druge slike pa je samo mešanje ostalih treh (RGB) kanalov.

    FYI, GtkImage je gradnik, ki je sposoben na zaslon prikazat sliko. GdkPixbuf pa struktura, ki hrani sliko. GdkPixmap pa je pravtako struktura, ki hrani sliko, vendar je zastarela in se zato priporoča uporaba GdkPixbuf oz. cairo

    Pa še en nasvet, mogoče je bolje se izogibat tem guchar tipom. Pri meni je ta tip v resnici bil signed char namesto unsigned char. Namesto guchar torej uporabi unsigned char ali pa uint8_t
  • napsy: hvala za tvoj odgovor, mi je zelo koristil.

    Sedaj me pa zanima samo še to, kako naj narišem črto v pixbuf.
    v GdkPixbuf naložim sliko, sedaj bi pa rad čez to sliko narisal črto.
    Sam sem preučil naslednje:
    [list=*]
    [*]Funkcija gdk_draw_line nad pixbuf-om ne deluje, ker deluje samo nad naslednikom GdkDrawable.[/*]
    [/list]
    [list=*]
    [*]Sam sem z uporabo cairo knjižnice naredil cairo surface in vse narisal, sliko s črto lahko tudi shranim kot pdf(cairo_surface_write_to_png), ne vem pa kako jo prikažem v GtkImage[/*]
    [/list]

    Prosim za pomoč pri eni izmed zgornjih možnosti!

    Lp:igor
  • napsy Član Ubuntu.si
    Za risanje priporočam, da površino obdeluješ s cairo, nato pa jo kasneje pretvoriš v pixbuf. Lahko si pomagaš s funkcijami gdk_cairo_create () in gdk_cairo_set_source_pixbuf ()
  • napsy: hvala za odgovor vendar ne razumem čist točno.

    Moja koda zgleda nekako takole:
       cairo_format_t format = (gdk_pixbuf_get_has_alpha(temp) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24);
    cairo_surface_t *surface = cairo_image_surface_create(format, gdk_pixbuf_get_width(temp), gdk_pixbuf_get_height(temp));
    cairo_t *cr = cairo_create(surface);
    gdk_cairo_set_source_pixbuf(cr, temp, 0, 0);
    cairo_paint(cr);

    cairo_set_source_rgb(cr, 1, 0, 0);
    cairo_set_line_width(cr, 4);
    cairo_move_to(cr, x_1, y_1);
    cairo_line_to(cr, event->x, event->y);
    cairo_stroke(cr);

    cairo_paint(cr);
    //cairo_surface_write_to_png(surface, \"a.png\");

    cairo_destroy(cr);


    sedaj bi pa rabil samo funkcjio ki namesto cairo_surface_write_to_png(surface, "a.png") zapiše spremenjeno sliko (narisana črta) v GdkPixbuf ?

    Najlepša hvala za odgovore (napsy)!
  • napsy Član Ubuntu.si
    S funkcijo cairo_image_surface_get_data() dobiš goli podatek o sliki. Za dimenzije uporabi

    width = cairo_image_surface_get_width(surface);
    format = cairo_image_surface_get_format(surface);
    stride = cairo_format_stride_for_width(format, width);
    height = cairo_image_surface_get_height(surface);
    S tem, da so goli podatki pri cairo zapisani v ARGB, če se prav spomnem. Se pravi prvi bajt je alfa kanal.
Za komentiranje se prijavite ali pa se vpišite.