Message-ID: <4340EEAA.8060904 at irisa.fr> Date: Mon, 03 Oct 2005 10:41:14 +0200 From: Sebastien Ferre Organization: IRISA MIME-Version: 1.0 To: Olivier Andrieu , lablgtk at math.nagoya-u.ac.jp Subject: Re: GTree: delaying the computation of a pixbuf upon visibility References: <43355ED4.5000004 at inria.fr> <433A46AE.8000004 at irisa.fr> <17211.57896.40053.753344 at karryall.dnsalias.org> <433CF2BA.8030204 at irisa.fr> <17215.60406.276599.274837 at karryall.dnsalias.org> In-Reply-To: <17215.60406.276599.274837 at karryall.dnsalias.org> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Olivier Andrieu wrote: > Sebastien Ferre [Friday 30 September 2005] : > > > > Hi, > > > > Olivier Andrieu wrote: > > > Sebastien Ferre [Wednesday 28 September 2005] : > > > > > > > > Hi, > > > > > > > > I'm working on a GUI in which there is a 'GTree.list_store' of > > > > thumbnails (look at http://www.irisa.fr/lande/ferre/camelis > > > > for screen captions). I use the library CamlImages for > > > > computing these thumbnails from JPEG pictures. > > > > > > Why don't you use GdkPixbuf for this ? It can load JPEG pictures. > > > > this is what I used at the beginning. But I noticed there was > > something like a memory leak as the process rapidly grew to more > > than 1Gb of memory, while I checked the loaded images were no more > > reachable. > > Ah. It might be a memory leak in lablgtk. I'd be interested if you > still have some code showing this problem. If you call many times the function 'pixmap_of_picture', you should exhibit the problem. It seems the data in local variable 'pixbuf' is never deallocated (while the use of Gc.finalize shows it do become unreachable, as expected). let default_mask ~width ~height = let msk = Gdk.Bitmap.create ~width ~height () in let gc = Gdk.GC.create msk in let colormap = Gdk.Color.get_system_colormap () in let _ = Gdk.GC.set_foreground gc (Gdk.Color.alloc ~colormap:colormap `WHITE) in let _ = Gdk.Draw.rectangle msk gc ~x:0 ~y:0 ~width ~height ~filled:true () in msk let pixmap_of_picture = (*let ht = Hashtbl.create 100 in*) fun ~maxside filename -> (*try Hashtbl.find ht filename with Not_found -> *) let pixbuf = GdkPixbuf.from_file filename in let w = GdkPixbuf.get_width pixbuf in let h = GdkPixbuf.get_height pixbuf in let scale = max maxside (max w h) / maxside in let width = w / scale in let height = h / scale in let dest = GdkPixbuf.create ~width ~height () in let _ = GdkPixbuf.scale ~dest:dest ~width ~height pixbuf in let pm, _ = GdkPixbuf.create_pixmap dest in let pixmap = new GDraw.pixmap ?mask:(Some (default_mask ~width ~height)) pm in (* BEWARE: crash if no mask is given *) Hashtbl.add ht filename pixmap; pixmap > > Also, CamlImages allows for loading directly a thumbnail from JPEG > > pictures, which is lighter. > > GdkPixbuf has a GdkPixbuf.from_file_at_size function that lets you do > that too (I hope so). I can't find it. Is it in a newer version ? (I have version 2.4.0). > > > > The problem is that computing these thumbnails is really slow. > > > > For example it takes about 20s for 100 thumbnails, whereas only > > > > a few are visible at one time. So I wonder if it is possible to > > > > delay these computations upon the visibility of a row of the list > > > > inside the scrolling window ? What I want is also to keep control on > > > > the scrolling and selecting while thumbnails are being computed > > > > and displayed. > > > > > > > > Here is the code I use to build a pixbuf from a JPEG file. Can it be > > > > made more efficient ? > > > > > > > > let pixbuf_of_jpeg = > > > > let ht = Hashtbl.create 100 in > > > > fun ~maxside filename -> > > > > try Hashtbl.find ht filename > > > > with Not_found -> > > > > let spec = { > > > > spec_width = Scale 0.2; > > > > spec_height = Scale 0.2; > > > > spec_aspect = Keep_at_most; > > > > spec_switch = Smaller_only; > > > > spec_x = 0; > > > > spec_y = 0} in > > > > let _, _, img = OJpeg.load_thumbnail filename [] spec in > > > > let img = OImages.rgb24 img in > > > > let w = img#width in > > > > let h = img#height in > > > > let scale = max maxside (max w h) / maxside in > > > > let width = w / scale in > > > > let height = h / scale in > > > > let newimage = img#resize None width height in > > > > let pixmap = OXimage2.pixmap_of_image (Gdk.Window.root_parent ()) > > > > None newimage#coerce in > > > > let pixbuf = GdkPixbuf.create ~width ~height () in > > > > GdkPixbuf.get_from_drawable ~dest:pixbuf pixmap#pixmap; > > > > Hashtbl.add ht filename pixbuf; > > > > pixbuf > > > > > > I see you're doing a pixmap_of_image, ie you're sending your image to > > > the server, then you do a GdkPixbuf.get_from_drawable, ie you're > > > asking the server to send the image data back. And GTK will send the > > > data to the server again when displaying the pixbuf. This doesn't seem > > > very efficient. > > > > I could not find a simpler way to do it. Is there a way to translate > > directly an image to a pixbuf ? > > Well you can always do a big loop that gets every pixel in the > camlimage and sets it in the gdkpixbuf. I'll try that. > > > > And now, here is the code I use for building the list. In the > > > > model I put the filename of the source picture, and in the > > > > view I use a 'cell_renderer_pixbuf' and redefine the > > > > cell_data_func. > > > > > > But why don't you have a pixbuf column in you model ? I'd do it > > > this way: > > > > Well, my knowledge of the library is quite limited. All I can do > > is scroll through the documentation, and guess the meaning of > > methods and functions from their name and type. The given examples > > are most helpful, but still limited... > > > > > - have a string column and a pixbuf column in your model > > > > What type should I use for creating a pixbuf column ? > > > > let thumb_pixbuf = cols_extent#add ??? > > let thumb_pixbuf = > cols_extent#add > (Gobject.Data.gobject : GdkPixbuf.t Gobject.data_conv) > Cheers, Sebastien