private void HandleAreaPrepared(object sender, System.EventArgs args)
        {
            pixbuf = PixbufUtils.TransformOrientation(loader.Pixbuf, orientation, false);

            if (thumb != null && pixbuf != null)
            {
                thumb.Composite(pixbuf, 0, 0,
                                pixbuf.Width, pixbuf.Height,
                                0.0, 0.0,
                                pixbuf.Width / (double)thumb.Width, pixbuf.Height / (double)thumb.Height,
                                Gdk.InterpType.Bilinear, 0xff);
            }

            if (thumb != null)
            {
                if (!ThumbnailGenerator.ThumbnailIsValid(thumb, uri))
                {
                    FSpot.ThumbnailGenerator.Default.Request(uri, 0, 256, 256);
                }
            }

            area_prepared = true;
            if (AreaUpdated != null)
            {
                AreaPrepared(this, new AreaPreparedArgs(false));
            }

            if (thumb != null)
            {
                thumb.Dispose();
            }
            thumb = null;
        }
예제 #2
0
 public override Gdk.Pixbuf Load(int width, int height)
 {
     Gdk.Pixbuf full    = this.Load();
     Gdk.Pixbuf rotated = PixbufUtils.TransformOrientation(full, this.GetOrientation(), true);
     Gdk.Pixbuf scaled  = PixbufUtils.ScaleToMaxSize(rotated, width, height);
     full.Dispose();
     return(scaled);
 }
예제 #3
0
        private static void RotateOrientation(string original_path, RotateDirection direction)
        {
            using (FSpot.ImageFile img = FSpot.ImageFile.Create(original_path)) {
                if (img is JpegFile)
                {
                    FSpot.JpegFile    jimg        = img as FSpot.JpegFile;
                    PixbufOrientation orientation = direction == RotateDirection.Clockwise
                                                ? PixbufUtils.Rotate90(img.Orientation)
                                                : PixbufUtils.Rotate270(img.Orientation);

                    jimg.SetOrientation(orientation);
                    jimg.SaveMetaData(original_path);
                }
                else if (img is PngFile)
                {
                    PngFile png       = img as PngFile;
                    bool    supported = false;

                    //FIXME there isn't much png specific here except the check
                    //the pixbuf is an accurate representation of the real file
                    //by checking the depth.  The check should be abstracted and
                    //this code made generic.
                    foreach (PngFile.Chunk c in png.Chunks)
                    {
                        PngFile.IhdrChunk ihdr = c as PngFile.IhdrChunk;

                        if (ihdr != null && ihdr.Depth == 8)
                        {
                            supported = true;
                        }
                    }

                    if (!supported)
                    {
                        throw new RotateException("Unable to rotate photo type", original_path);
                    }

                    string backup = ImageFile.TempPath(original_path);
                    using (Stream stream = File.Open(backup, FileMode.Truncate, FileAccess.Write)) {
                        using (Pixbuf pixbuf = img.Load()) {
                            PixbufOrientation fake = (direction == RotateDirection.Clockwise) ? PixbufOrientation.RightTop : PixbufOrientation.LeftBottom;
                            using (Pixbuf rotated = PixbufUtils.TransformOrientation(pixbuf, fake)) {
                                img.Save(rotated, stream);
                            }
                        }
                    }
                    File.Copy(backup, original_path, true);
                    File.Delete(backup);
                }
                else
                {
                    throw new RotateException("Unable to rotate photo type", original_path);
                }
            }
        }
예제 #4
0
        public Point ImageCoordsToWindow(Point image)
        {
            if (Pixbuf == null)
            {
                return(Point.Zero);
            }

            image = PixbufUtils.TransformOrientation(Pixbuf.Width, Pixbuf.Height, image, pixbuf_orientation);
            int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
            int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;

            return(new Point((int)Math.Floor(image.X * (double)(scaled_width - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Width : Pixbuf.Height) - 1) + 0.5) + x_offset,
                             (int)Math.Floor(image.Y * (double)(scaled_height - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Height : Pixbuf.Width) - 1) + 0.5) + y_offset));
        }
예제 #5
0
        protected Gdk.Pixbuf TransformAndDispose(Gdk.Pixbuf orig)
        {
            if (orig == null)
            {
                return(null);
            }

            Gdk.Pixbuf rotated = PixbufUtils.TransformOrientation(orig, this.Orientation, true);
            //ValidateThumbnail (photo, rotated);
            if (rotated != orig)
            {
                orig.Dispose();
            }

            return(rotated);
        }
예제 #6
0
        public Gdk.Pixbuf GetEmbeddedThumbnail()
        {
            if (this.ExifData.Data.Length > 0)
            {
                MemoryStream mem     = new MemoryStream(this.ExifData.Data);
                Gdk.Pixbuf   thumb   = new Gdk.Pixbuf(mem);
                Gdk.Pixbuf   rotated = PixbufUtils.TransformOrientation(thumb, this.Orientation);

                if (rotated != thumb)
                {
                    thumb.Dispose();
                }

                mem.Close();
                return(rotated);
            }
            return(null);
        }
예제 #7
0
        public Point WindowCoordsToImage(Point win)
        {
            if (Pixbuf == null)
            {
                return(Point.Zero);
            }

            int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
            int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;

            win.X = Clamp(win.X - x_offset, 0, (int)scaled_width - 1);
            win.Y = Clamp(win.Y - y_offset, 0, (int)scaled_height - 1);

            win = PixbufUtils.TransformOrientation((int)scaled_width, (int)scaled_height, win, PixbufUtils.ReverseTransformation(pixbuf_orientation));

            return(new Point((int)Math.Floor(win.X * (double)(((int)PixbufOrientation <= 4 ? Pixbuf.Width : Pixbuf.Height) - 1) / (double)(scaled_width - 1) + .5),
                             (int)Math.Floor(win.Y * (double)(((int)PixbufOrientation <= 4 ? Pixbuf.Height : Pixbuf.Width) - 1) / (double)(scaled_height - 1) + .5)));
        }
예제 #8
0
        public Rectangle ImageCoordsToWindow(Rectangle image)
        {
            if (Pixbuf == null)
            {
                return(Gdk.Rectangle.Zero);
            }

            image = PixbufUtils.TransformOrientation(Pixbuf.Width, Pixbuf.Height, image, pixbuf_orientation);
            int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
            int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;

            Gdk.Rectangle win = Gdk.Rectangle.Zero;
            win.X      = (int)Math.Floor(image.X * (double)(scaled_width - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Width : Pixbuf.Height) - 1) + 0.5) + x_offset;
            win.Y      = (int)Math.Floor(image.Y * (double)(scaled_height - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Height : Pixbuf.Width) - 1) + 0.5) + y_offset;
            win.Width  = (int)Math.Floor((image.X + image.Width) * (double)(scaled_width - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Width : Pixbuf.Height) - 1) + 0.5) - win.X + x_offset;
            win.Height = (int)Math.Floor((image.Y + image.Height) * (double)(scaled_height - 1) / (((int)pixbuf_orientation <= 4 ? Pixbuf.Height : Pixbuf.Width) - 1) + 0.5) - win.Y + y_offset;

            return(win);
        }
    public static Gdk.Pixbuf GetThumbnail(Exif.ExifData data)
    {
        byte [] thumb_data = data.Data;
        if (thumb_data.Length > 0)
        {
            PixbufOrientation orientation = GetOrientation(data);

            using (MemoryStream mem = new MemoryStream(thumb_data)) {
                Gdk.Pixbuf thumb = new Gdk.Pixbuf(mem);

                Gdk.Pixbuf rotated = PixbufUtils.TransformOrientation(thumb, orientation);

                if (rotated != thumb)
                {
                    thumb.Dispose();
                }
                return(rotated);
            }
        }
        return(null);
    }
        public void Load(Uri uri)
        {
            this.uri = uri;

            delay.Stop();

            if (!done_reading)
            {
                Close();
            }

            done_reading  = false;
            area_prepared = false;
            damage        = Gdk.Rectangle.Zero;

            using (ImageFile img = ImageFile.Create(uri)) {
                orientation = Accelerometer.GetViewOrientation(img.Orientation);

                try {
                    PixbufOrientation thumb_orientation = Accelerometer.GetViewOrientation(PixbufOrientation.TopLeft);
                    thumb = new Gdk.Pixbuf(ThumbnailGenerator.ThumbnailPath(uri));
                    thumb = PixbufUtils.TransformOrientation(thumb, thumb_orientation);

                    if (FSpot.ColorManagement.IsEnabled && !thumb.HasAlpha)
                    {
                        if (img.GetProfile() == null)
                        {
                            FSpot.ColorManagement.PhotoImageView.Transform = FSpot.ColorManagement.StandartTransform();
                        }
                        else
                        {
                            FSpot.ColorManagement.PhotoImageView.Transform = FSpot.ColorManagement.CreateTransform(thumb, img.GetProfile());
                        }
                    }
                    else
                    {
                        FSpot.ColorManagement.PhotoImageView.Transform = null;
                    }
                } catch (System.Exception e) {
                    //FSpot.ThumbnailGenerator.Default.Request (uri.ToString (), 0, 256, 256);
                    if (!(e is GLib.GException))
                    {
                        System.Console.WriteLine(e.ToString());
                    }
                }

                System.IO.Stream nstream = img.PixbufStream();
                if (nstream == null)
                {
                    FileLoad(img);
                    return;
                }
                else
                {
                    stream = new StreamWrapper(nstream);
                }

                loader = new Gdk.PixbufLoader();
                loader.AreaPrepared += ap;
                loader.AreaUpdated  += au;
                loader.Closed       += ev;

                if (AreaPrepared != null && thumb != null)
                {
                    pixbuf = thumb;
                    AreaPrepared(this, new AreaPreparedArgs(true));
                }

                ThumbnailGenerator.Default.PushBlock();
                //AsyncIORead (null);
                if (nstream is IOChannel)
                {
                    ((IOChannel)nstream).DataReady += IOChannelRead;
                }
                else
                {
                    delay.Start();
                }
            }
        }
예제 #11
0
        void PaintRectangle(Rectangle area, InterpType interpolation)
        {
            int x_offset = scaled_width < Allocation.Width ? (int)(Allocation.Width - scaled_width) / 2 : -XOffset;
            int y_offset = scaled_height < Allocation.Height ? (int)(Allocation.Height - scaled_height) / 2 : -YOffset;

            //Draw background
            if (y_offset > 0)                   //Top
            {
                PaintBackground(new Rectangle(0, 0, Allocation.Width, y_offset), area);
            }
            if (x_offset > 0)                   //Left
            {
                PaintBackground(new Rectangle(0, y_offset, x_offset, (int)scaled_height), area);
            }
            if (x_offset >= 0)                  //Right
            {
                PaintBackground(new Rectangle(x_offset + (int)scaled_width, y_offset, Allocation.Width - x_offset - (int)scaled_width, (int)scaled_height), area);
            }
            if (y_offset >= 0)                  //Bottom
            {
                PaintBackground(new Rectangle(0, y_offset + (int)scaled_height, Allocation.Width, Allocation.Height - y_offset - (int)scaled_height), area);
            }

            if (Pixbuf == null)
            {
                return;
            }

            area.Intersect(new Rectangle(x_offset, y_offset, (int)scaled_width, (int)scaled_height));

            if (area.Width <= 0 || area.Height <= 0)
            {
                return;
            }

            //Short circuit for 1:1 zoom
            if (zoom == 1.0 &&
                !Pixbuf.HasAlpha &&
                Pixbuf.BitsPerSample == 8 &&
                pixbuf_orientation == ImageOrientation.TopLeft)
            {
                GdkWindow.DrawPixbuf(Style.BlackGC,
                                     Pixbuf,
                                     area.X - x_offset, area.Y - y_offset,
                                     area.X, area.Y,
                                     area.Width, area.Height,
                                     RgbDither.Max,
                                     area.X - x_offset, area.Y - y_offset);
                return;
            }

            Rectangle pixbuf_area = PixbufUtils.TransformOrientation((int)scaled_width,
                                                                     (int)scaled_height,
                                                                     new Rectangle((area.X - x_offset),
                                                                                   (area.Y - y_offset),
                                                                                   area.Width,
                                                                                   area.Height),
                                                                     PixbufUtils.ReverseTransformation(pixbuf_orientation));

            using (Pixbuf temp_pixbuf = new Pixbuf(Colorspace.Rgb, false, 8, pixbuf_area.Width, pixbuf_area.Height)) {
                if (Pixbuf.HasAlpha)
                {
                    temp_pixbuf.Fill(0x00000000);
                }

                Pixbuf.CompositeColor(temp_pixbuf,
                                      0, 0,
                                      pixbuf_area.Width, pixbuf_area.Height,
                                      -pixbuf_area.X, -pixbuf_area.Y,
                                      zoom, zoom,
                                      zoom == 1.0 ? InterpType.Nearest : interpolation, 255,
                                      pixbuf_area.X, pixbuf_area.Y,
                                      CheckPattern.CheckSize, CheckPattern.Color1, CheckPattern.Color2);


                ApplyColorTransform(temp_pixbuf);

                using (var dest_pixbuf = PixbufUtils.TransformOrientation(temp_pixbuf, pixbuf_orientation)) {
                    GdkWindow.DrawPixbuf(Style.BlackGC,
                                         dest_pixbuf,
                                         0, 0,
                                         area.X, area.Y,
                                         area.Width, area.Height,
                                         RgbDither.Max,
                                         area.X - x_offset, area.Y - y_offset);
                }
            }
        }