protected Gdk.Pixbuf TransformAndDispose(Gdk.Pixbuf orig) { if (orig == null) { return(null); } Gdk.Pixbuf rotated = orig.TransformOrientation(Orientation); orig.Dispose(); return(rotated); }
public static void GenerateMipMap (IPhoto photo) { var mipmap_uri = MipMapUri (photo); Log.DebugFormat ("Generating mipmap for {0} - {1}", photo.Uri.ToString (), mipmap_uri.AbsoluteUri); var file = GLib.FileFactory.NewForUri (photo.Uri); var pixbuf = new Gdk.Pixbuf (new GLib.GioStream (file.Read (null))); var imagefile = TagLib.File.Create (new GIOTagLibFileAbstraction () { Uri = photo.Uri }) as TagLib.Image.File; var tag = imagefile.ImageTag; // Correct orientation pixbuf = pixbuf.TransformOrientation (tag.Orientation); // Determine mode var mode = pixbuf.Width > pixbuf.Height ? ScaleMode.Width : ScaleMode.Height; var longest = mode == ScaleMode.Width ? pixbuf.Width : pixbuf.Height; double scale_factor = Math.Max ((double) longest / 1600, 1.0); MipMapFile map = new MipMapFile (); List<Gdk.Pixbuf> pixbufs = new List<Gdk.Pixbuf>(7); // Six or seven on average if (scale_factor > 1.0) { using (var tmp = pixbuf) pixbuf = pixbuf.ScaleSimple ((int) Math.Round (pixbuf.Width / scale_factor), (int) Math.Round (pixbuf.Height / scale_factor), Gdk.InterpType.Bilinear); } int max; do { max = Math.Max (pixbuf.Width, pixbuf.Height); pixbufs.Add (pixbuf); pixbuf = pixbuf.ScaleSimple (pixbuf.Width / 2, pixbuf.Height / 2, Gdk.InterpType.Bilinear); } while (max > 64); pixbuf.Dispose (); // As the mipmap items are built from largest -> smallest, we need to add them in reverse. pixbufs.Reverse (); foreach (var buf in pixbufs) { map.Add (buf); } map.WriteToUri (mipmap_uri); }