Esempio n. 1
0
        protected override RequestedAction LayoutImage(ImageState s)
        {
            //Only activated if both width and height are specified, and mode=crop.
            if (s.settings.Mode != FitMode.Crop || s.settings.Width < 0 || s.settings.Height < 0)
            {
                return(RequestedAction.None);
            }

            var finalMode = s.settings.Get("c.finalmode", FitMode.Pad);

            var regions = SalientArea.FromQuery(s.settings);

            if (regions.Length == 0)
            {
                return(RequestedAction.None);
            }


            var a = new Aligner {
                Regions              = regions,
                ImageSize            = s.originalSize,
                TargetSize           = new Size(s.settings.Width, s.settings.Height),
                NeverCropSalientArea = finalMode != FitMode.Crop,
                Zoom = regions[0].Area.Width > 0 && regions[0].Area.Height > 0 && s.settings.Get("c.zoom", false)
            };

            s.copyRect = a.GetCrop();

            s.ValidateCropping();

            //So, if we haven't met the aspect ratio yet, what mode will we pass on?
            s.settings.Mode = finalMode;

            return(RequestedAction.None);
        }
Esempio n. 2
0
        internal RectangleF GetCrop()
        {
            if (Zoom)
            {
                return(GetZoomCrop());
            }


            var salientBounds = SalientBoundingBox();

            var idealCropSize = PolygonMath.ScaleInside(TargetSize, ImageSize);

            var fits = PolygonMath.FitsInside(salientBounds.Size, idealCropSize);

            // If there's no need to crop out a salient region, then center on the salient bounding box and align within the image bounds.
            if (fits)
            {
                return(PolygonMath.AlignWithin(new RectangleF(PointF.Empty, idealCropSize),
                                               new RectangleF(PointF.Empty, ImageSize), PolygonMath.Midpoint(salientBounds)));
            }

            if (NeverCropSalientArea)
            {
                var compromiseCrop = new SizeF(Math.Max(salientBounds.Width, idealCropSize.Width),
                                               Math.Max(salientBounds.Height, idealCropSize.Height));

                // Don't worry about 3 pixels or less, that's just annoying.
                if (compromiseCrop.Width - idealCropSize.Width <= 3 &&
                    compromiseCrop.Height - idealCropSize.Height <= 3)
                {
                    compromiseCrop = idealCropSize;
                }

                return(PolygonMath.AlignWithin(new RectangleF(PointF.Empty, compromiseCrop),
                                               new RectangleF(PointF.Empty, ImageSize), PolygonMath.Midpoint(salientBounds)));
            }

            // Find the least bad crop (brute force)
            var vertical = salientBounds.Height > idealCropSize.Height;

            var choiceCount = vertical
                ? salientBounds.Height - idealCropSize.Height
                : salientBounds.Width - idealCropSize.Width;

            var searchArea = new RectangleF(vertical ? 0 : salientBounds.X, vertical ? salientBounds.Y : 0, vertical ? idealCropSize.Width : salientBounds.Width, vertical ? salientBounds.Height : idealCropSize.Height);

            var initialWindow = PolygonMath.AlignWith(new RectangleF(PointF.Empty, idealCropSize), searchArea,
                                                      ContentAlignment.TopLeft);

            double bestVolume = 0;
            var    bestCrop   = initialWindow;

            for (var i = 0; i < choiceCount; i++)
            {
                var window = initialWindow;
                window.Offset(vertical ? 0 : i, vertical ? i : 0);

                var volume = SalientArea.IntersectVolume(window, Regions);
                if (volume > bestVolume)
                {
                    bestVolume = volume;
                    bestCrop   = window;
                }
            }
            return(bestCrop);
        }