Esempio n. 1
0
        protected override RequestedAction LayoutImage(ImageState s)
        {
            if (s.sourceBitmap == null) return RequestedAction.None;

            //Parse carve data bitmap
            if (!string.IsNullOrEmpty(s.settings["carve.data"])) {
                string[] parts = s.settings["carve.data"].Split('|');
                //Parse block count and string
                var block_count = int.Parse(parts[0]);
                var carveString = new LzwDecoder("012").Decode(PathUtils.FromBase64UToBytes(parts[1]));

                float block_size = (int)Math.Floor(Math.Sqrt(s.originalSize.Width * s.originalSize.Height / (double)block_count));

                var carveData = new CarveDataPlotter() {
                    BlockCount=block_count,
                    Stride = (int)Math.Ceiling((float)s.originalSize.Width / block_size),
                    Rows = (int)Math.Ceiling((float)s.originalSize.Height / block_size)
                };

                carveData.Init(carveString);

                Size remove = carveData.GetRemovalSpace(s.originalSize.Width,s.originalSize.Height,(int)block_size);

                if (remove.Width / s.originalSize.Width > remove.Height / s.originalSize.Height) {
                    s.originalSize = new Size(s.originalSize.Width - remove.Width, s.originalSize.Height);
                } else {
                    s.originalSize = new Size(s.originalSize.Width, s.originalSize.Height - remove.Height);
                }

                //Save later
                s.Data[CarveData] = carveData;
            }

            return RequestedAction.None;
        }
        protected override RequestedAction PrepareDestinationBitmap(ImageState s)
        {
            if (!this.IsDiagnosticRequest(s.settings)) return RequestedAction.None;

            // Rather than allow the normal process, we will throw an
            // AlternateResponseException that contains the data we *really*
            // want to return.
            var info = new LayoutInformation(s);
            var serializer = new JsonSerializer();

            // Check to see if indented JSON has been requested.  This is useful
            // for human-readable output.
            if (s.settings.Get("j.indented", false))
            {
                serializer.Formatting = Formatting.Indented;
            }

            serializer.Converters.Add(new InstructionsConverter());

            StringWriter sw = new StringWriter();
            serializer.Serialize(sw, info);
            var bytes = System.Text.Encoding.UTF8.GetBytes(sw.ToString());

            throw new AlternateResponseException(
                "Resizing pipeline was canceled as JSON data was requested instead.",
                "application/json; charset=utf-8",
                bytes);
        }
Esempio n. 3
0
        protected override RequestedAction LayoutImage(ImageState s)
        {
            if (s.sourceBitmap == null) return RequestedAction.None;

            //percentpadding. Percentage is 0-100, multiplied by the average of the width and height.
            double percentpadding = s.settings.Get<double>("trim.percentpadding", 0) / 100;

            int? threshold = s.settings.Get<int>("trim.threshold");
            if (threshold != null) {
                if (threshold < 0) threshold = 0; if (threshold > 255) threshold = 255;

                Rectangle box = new BoundingBoxFinder().FindBoxSobel(s.sourceBitmap, new Rectangle(0, 0, s.sourceBitmap.Width, s.sourceBitmap.Height), (byte)threshold);
                //Add padding
                int paddingPixels = (int)Math.Ceiling(percentpadding * (box.Width + box.Height) / 2);
                box.X = Math.Max(0, box.X - paddingPixels);
                box.Y= Math.Max(0, box.Y - paddingPixels);
                box.Width = Math.Min(s.sourceBitmap.Width, box.Width + paddingPixels * 2);
                box.Height = Math.Min(s.sourceBitmap.Height, box.Height + paddingPixels * 2);

                //Adjust s.originalSize so the layout occurs properly.
                s.originalSize = box.Size;
                s.Data[RectDataKey] = box;
            }
            return RequestedAction.None;
        }
Esempio n. 4
0
        protected override RequestedAction PostRenderImage(ImageState s)
        {
            var color = s.destBitmap.GetPixel(0,0);

            Console.WriteLine("PostLayoutEffects " + ++i + " color at (0,0): " + color);
            return base.PostRenderImage(s);
        }
        protected override RequestedAction PostRenderImage(ImageState s)
        {
            _delays = _delays ?? GetDelays(s.sourceBitmap);

            _visitor((Bitmap)s.destBitmap.Clone(), s.destGraphics, _delays[_visitIndex++]);

            return base.PostRenderImage(s);
        }
Esempio n. 6
0
        public PointF[] GetOverlayParalellogram(Overlay o, Size nativeSize, ImageState translateToFinalCoordinateSpace)
        {
            //What's the polygon w/h?
            double cw = PolygonMath.Dist(o.Poly[0], o.Poly[1]);
            double ch = PolygonMath.Dist(o.Poly[1], o.Poly[2]);
            //Take a copy to shrink to content size
            double w = cw;
            double h = ch;

            double aspect = (double)nativeSize.Height / (double)nativeSize.Width;

            //If specified, what percentage of the space do we use?
            if (o.PolyWidthInLogoPixels > 0) {
                w = cw * (double)nativeSize.Width / o.PolyWidthInLogoPixels;
                if (o.RespectOnlyMatchingBound) h = w * aspect;
            }

            if (o.PolyHeightInLogoPixels > 0) {
                h = ch * (double)nativeSize.Height / o.PolyHeightInLogoPixels;
                if (o.RespectOnlyMatchingBound && o.PolyWidthInLogoPixels <= 0) w = h / aspect;
            }

            //Shrink to keep aspect ratio
            if (w / h > 1 / aspect) {
                w = h / aspect;
            } else {
                h = w * aspect;
            }
            //Let's define our width/height offsets
            double ox = 0; double oy = 0; ;

            //Apply alignment to ox, oy
            if (o.Align == ContentAlignment.BottomLeft || o.Align == ContentAlignment.MiddleLeft || o.Align == ContentAlignment.TopLeft)
                ox = 0;
            if (o.Align == ContentAlignment.BottomCenter || o.Align == ContentAlignment.MiddleCenter || o.Align == ContentAlignment.TopCenter)
                ox = (cw - w) / 2;
            if (o.Align == ContentAlignment.BottomRight || o.Align == ContentAlignment.MiddleRight || o.Align == ContentAlignment.TopRight)
                ox = cw - w;
            if (o.Align == ContentAlignment.TopLeft || o.Align == ContentAlignment.TopCenter || o.Align == ContentAlignment.TopRight)
                oy = 0;
            if (o.Align == ContentAlignment.MiddleLeft || o.Align == ContentAlignment.MiddleCenter || o.Align == ContentAlignment.MiddleRight)
                oy = (ch - h) / 2;
            if (o.Align == ContentAlignment.BottomLeft || o.Align == ContentAlignment.BottomCenter || o.Align == ContentAlignment.BottomRight)
                oy = ch - h;

            //Now, we need to rotate everything to match the rotation of the original parallelogram
            double angle = Math.Atan2(o.Poly[1].Y - o.Poly[0].Y, o.Poly[1].X - o.Poly[0].X);

            PointF[] t = new PointF[4];
            t[0] = CreateVector(CreateVector(o.Poly[0], angle, ox), angle + Math.PI / 2, oy);
            t[1] = CreateVector(t[0], angle, w);
            t[2] = CreateVector(t[1], angle + Math.PI / 2, h);
            t[3] = CreateVector(t[0], angle + Math.PI / 2, h);

            //Translate the points if a ImageState instance was specified
            if (translateToFinalCoordinateSpace != null) return this.TranslatePoints(t, translateToFinalCoordinateSpace);
            return t;
        }
        protected override RequestedAction PostCreateImageAttributes(ImageState s)
        {
            if (s.copyAttibutes == null) return RequestedAction.None;

            if (!s.settings.WasOneSpecified(GetSupportedQuerystringKeys().ToArray())) return RequestedAction.None;

            s.copyAttibutes.SetColorMatrix(new ColorMatrix(Grayscale()));
            return RequestedAction.None;
        }
Esempio n. 8
0
 protected override RequestedAction PostLayoutImage(ImageState s)
 {
     //Now we offset copyRect so it works properly.
     if (s.Data.ContainsKey(RectDataKey)){
         Rectangle box = (Rectangle)s.Data[RectDataKey];
         s.copyRect = new RectangleF(s.copyRect.X + box.X, s.copyRect.Y + box.Y,s.copyRect.Width,s.copyRect.Height);
     }
     return RequestedAction.None;
 }
Esempio n. 9
0
        /// <summary>
        /// Builds an FIBitmap from the stream and job.Settings 
        /// </summary>
        /// <param name="s"></param>
        /// <param name="job"></param>
        /// <returns></returns>
        protected FIBITMAP buildFiBitmap(ref FIBITMAP original, ImageJob job, bool supportsTransparency, bool mayUnloadOriginal)
        {
            ResizeSettings settings = job.Settings;
            if (original.IsNull) return FIBITMAP.Zero;
            FIBITMAP final = FIBITMAP.Zero;

            //Find the image size
            Size orig = new Size((int)FreeImage.GetWidth(original), (int)FreeImage.GetHeight(original));

            //Calculate the new size of the image and the canvas.
            ImageState state = new ImageState(settings, orig, true);
            c.CurrentImageBuilder.Process(state);
            RectangleF imageDest = PolygonMath.GetBoundingBox(state.layout["image"]);

            if (imageDest.Width != orig.Width || imageDest.Height != orig.Height) {
                //Rescale
                bool temp;
                final = FreeImage.Rescale(original, (int)imageDest.Width, (int)imageDest.Height, FreeImageScalingPlugin.ParseResizeAlgorithm(settings["fi.scale"], FREE_IMAGE_FILTER.FILTER_BOX, out temp));
                if (mayUnloadOriginal) FreeImage.UnloadEx(ref original);
                if (final.IsNull) return FIBITMAP.Zero;
            } else {
                final = original;
            }

            RGBQUAD bgcolor = default(RGBQUAD);
            bgcolor.Color = settings.BackgroundColor;
            if (settings.BackgroundColor == Color.Transparent && !supportsTransparency)
                bgcolor.Color = Color.White;

            //If we need to leave padding, do so.
            BoxPadding outsideImage = new BoxPadding(imageDest.Left, imageDest.Top, state.destSize.Width - imageDest.Right, state.destSize.Height - imageDest.Bottom);

            if (outsideImage.All != 0) {
                var old = final;
                //Extend canvas
                final = FreeImage.EnlargeCanvas<RGBQUAD>(old,
                            (int)outsideImage.Left, (int)outsideImage.Top, (int)outsideImage.Right, (int)outsideImage.Bottom,
                            bgcolor.Color != Color.Transparent ? new Nullable<RGBQUAD>(bgcolor) : null,
                            FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA);
                if (old == original) {
                    if (mayUnloadOriginal) {
                        FreeImage.UnloadEx(ref original);
                        old = original;
                    }
                } else {
                    FreeImage.UnloadEx(ref old); //'old' has the original value of 'final', which we allocated.
                }
                if (final.IsNull) return FIBITMAP.Zero;
            }

            return final;
        }
Esempio n. 10
0
        protected override RequestedAction RenderImage(ImageState s)
        {
            //Skip this when we are doing simulations
            if (s.destGraphics == null) return RequestedAction.None;

            //If there's pre-rendering involved this optimization is utterly pointless.
            if (s.preRenderBitmap != null) return RequestedAction.None;

            //Find out what the speed setting is.
            int speed = 0;
            if (string.IsNullOrEmpty(s.settings["speed"]) || !int.TryParse(s.settings["speed"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out speed)) speed = 0;

            if (speed < 1) return RequestedAction.None;

            s.destGraphics.CompositingMode = CompositingMode.SourceCopy;
            s.destGraphics.CompositingQuality = CompositingQuality.HighSpeed;
            if (speed == 1)
                s.destGraphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
            else
                s.destGraphics.InterpolationMode = InterpolationMode.Bilinear;

            s.destGraphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
            s.destGraphics.SmoothingMode = SmoothingMode.HighSpeed;

            s.copyAttibutes.SetWrapMode(WrapMode.TileFlipXY);

            if (speed < 3) {
                s.destGraphics.DrawImage(s.sourceBitmap, PolygonMath.getParallelogram(s.layout["image"]), s.copyRect, GraphicsUnit.Pixel, s.copyAttibutes);

            } else if (speed < 4) {
                Rectangle midsize = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(s.layout["image"]));

                using (Image thumb = s.sourceBitmap.GetThumbnailImage(midsize.Width, midsize.Height, delegate() { return false; }, IntPtr.Zero)) {
                    double xfactor = (double)thumb.Width / (double)s.sourceBitmap.Width;
                    double yfactor = (double)thumb.Height / (double)s.sourceBitmap.Height;
                    RectangleF copyPart = new RectangleF((float)(s.copyRect.Left * xfactor),
                                                        (float)(s.copyRect.Top * yfactor),
                                                        (float)(s.copyRect.Width * xfactor),
                                                        (float)(s.copyRect.Height * yfactor));
                    if (Math.Floor(copyPart.Height) == thumb.Height || Math.Ceiling(copyPart.Height) == thumb.Height) copyPart.Height = thumb.Height;
                    if (Math.Floor(copyPart.Width) == thumb.Width || Math.Ceiling(copyPart.Width) == thumb.Width) copyPart.Width = thumb.Width;
                    s.destGraphics.DrawImage(thumb, PolygonMath.getParallelogram(s.layout["image"]), copyPart, GraphicsUnit.Pixel, s.copyAttibutes);
                }
            } else {
                RectangleF box = PolygonMath.GetBoundingBox(PolygonMath.getParallelogram(s.layout["image"]));
                s.destGraphics.CompositingMode = CompositingMode.SourceCopy;
                s.destGraphics.DrawImage(s.sourceBitmap, box.Left, box.Top, box.Width, box.Height);
            }

            return RequestedAction.Cancel;
        }
Esempio n. 11
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;

            //Calculate bounding box for all coordinates specified.
            double[] focus = NameValueCollectionExtensions.GetList<double>(s.settings, "c.focus", null, 2, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72);
            if (focus == null) return RequestedAction.None;
            RectangleF box = PolygonMath.GetBoundingBox(focus);

            var bounds = new RectangleF(new PointF(0,0),s.originalSize);
            //Clip box to original image bounds
            box = PolygonMath.ClipRectangle(box, bounds);

            var targetSize = new SizeF(s.settings.Width,s.settings.Height);

            SizeF copySize;

            //Now, we can either crop as closely as possible or as loosely as possible.
            if (NameValueCollectionExtensions.Get<bool>(s.settings, "c.zoom", false) && box.Width > 0 && box.Height > 0) {
                //Crop close
                copySize = PolygonMath.ScaleOutside(box.Size, targetSize);
            } else {
                //Crop minimally
                copySize = PolygonMath.ScaleInside(targetSize, bounds.Size);
                //Ensure it's outside the box
                if (!PolygonMath.FitsInside(box.Size,copySize)) copySize = PolygonMath.ScaleOutside(box.Size, copySize);

            }
            //Clip to bounds.
            box = PolygonMath.ClipRectangle(PolygonMath.ExpandTo(box, copySize), bounds);

            s.copyRect = box;

            ///What is the vertical and horizontal aspect ratio different in result pixels?
            var padding = PolygonMath.ScaleInside(box.Size, targetSize);
            padding = new SizeF(targetSize.Width - padding.Width, targetSize.Height - padding.Height);

            //So, if we haven't met the aspect ratio yet, what mode will we pass on?
            var finalmode = NameValueCollectionExtensions.Get<FitMode>(s.settings, "c.finalmode", FitMode.Pad);

            //Crop off 1 or 2 pixels instead of padding without worrying too much
            if (finalmode == FitMode.Pad && padding.Width + padding.Height < 3) finalmode = FitMode.Crop;

            s.settings.Mode = finalmode;

            return RequestedAction.None;
        }
Esempio n. 12
0
        protected override RequestedAction PostRenderImage(ImageState s)
        {
            if (s.destBitmap == null) 
                return RequestedAction.None;
            if (!s.settings.WasOneSpecified(GetSupportedQuerystringKeys().ToArray()))
                return RequestedAction.None;;
            int blurSize; 
            if (!int.TryParse(s.settings["ipt.blur"], out blurSize))
            {
                return RequestedAction.None;
            }

            new GaussianBlur(1.4, blurSize).ApplyInPlace(s.destBitmap);

            return RequestedAction.None;
        }
Esempio n. 13
0
        protected override RequestedAction RenderOverlays(ImageState s)
        {
            // Get 'sample' from the querystring
            string sample = s.settings["sample"];

            //Don't try to draw the string if it is empty, or if this is a 'simulation' render
            if (string.IsNullOrEmpty(sample) || s.destGraphics == null) return RequestedAction.None;

            //Let's use Arial, and make sure the text fits inside the bitmap width.
            System.Drawing.Font font = new System.Drawing.Font("Arial",
                (float)(s.destBitmap.Width / (sample.Length * 1.5f)), System.Drawing.GraphicsUnit.Pixel);

            //Draw the text at the top left corner of the resulting image.
            s.destGraphics.DrawString(sample, font, System.Drawing.Brushes.Black, 0, 0);

            return RequestedAction.None;
        }
Esempio n. 14
0
        protected override RequestedAction PostLayoutImage(ImageState s)
        {
            base.PostLayoutImage(s);

            if (!limits.HasImageSize) return RequestedAction.None;//Skip this unless we have image size limits

            SizeF box = s.layout.GetBoundingBox().Size;

            double wFactor = box.Width / limits.ImageSize.Width;
            double hFactor = box.Height / limits.ImageSize.Height;

            double scaleFactor = wFactor > hFactor ? wFactor : hFactor;
            if (scaleFactor > 1) {
                //The bounding box exceeds the ImageSize. Scale down until it fits.
                s.layout.Scale(1 / scaleFactor, new PointF(0, 0));
            }

            return RequestedAction.None;
        }
Esempio n. 15
0
        protected override RequestedAction LayoutEffects(ImageState s)
        {
            float shadowWidth = s.settings.Get<float>("shadowWidth", 0);
            if (shadowWidth != 0) {

                var offset = NameValueCollectionExtensions.GetList<float>(s.settings, "shadowOffset", 0, 2);
                PointF shadowOffset =  offset == null ? new PointF(0,0) : new PointF(offset[0], offset[1]);

                //Clone last ring, then offset it - provides the inner bounds of the shadow later
                s.layout.AddInvisiblePolygon("shadowInner", PolygonMath.MovePoly(s.layout.LastRing.points, shadowOffset));

                //Determine the outer bound of the shadow
                s.layout.AddRing("shadow", PolygonMath.InflatePoly(s.layout.LastRing.points, new float[]{
                    Math.Max(0, shadowWidth - shadowOffset.Y),
                    Math.Max(0, shadowWidth + shadowOffset.X),
                    Math.Max(0, shadowWidth + shadowOffset.Y),
                    Math.Max(0, shadowWidth - shadowOffset.X)
                }));
            }
            return RequestedAction.None;
        }
Esempio n. 16
0
        protected override RequestedAction PostRenderImage(ImageState s)
        {
            if (s.destBitmap == null) return RequestedAction.None;
            string str = null;
            int i = 0;

             if ("true".Equals(s.settings["r.autoeyes"], StringComparison.OrdinalIgnoreCase)) {
                 List<ObjRect> eyes;
                 using (var ed = new EyeDetection()) eyes = ed.DetectFeatures(s.sourceBitmap);

                 List<PointF> points = new List<PointF>();
                 foreach(ObjRect r in eyes) { points.Add(new PointF(r.X,r.Y)); points.Add(new PointF(r.X2,r.Y2));}
                 PointF[] newPoints = c.CurrentImageBuilder.TranslatePoints(points.ToArray(),s.originalSize,new ResizeSettings(s.settings));
                 using (Graphics g = Graphics.FromImage(s.destBitmap)){
                     for(i =0; i < newPoints.Length -1; i+=2){
                         float x1 = newPoints[i].X;
                         float y1 = newPoints[i].Y;
                         float x2 = newPoints[i + 1].X;
                         float y2 = newPoints[i + 1].Y;
                         float t;
                         if (x1 > x2){ t = x2; x2  =x1; x1 = t;}
                         if (y1 > y2){ t = y1; y1 = y2; y2 = t;}

                         g.DrawRectangle(eyes[i /2].Feature == FeatureType.Eye ? Pens.Green : Pens.Gray,new Rectangle((int)x1,(int)y1,(int)(x2-x1),(int)(y2-y1)));
                     }
                 }
             }

            str = s.settings["r.filter"]; //radius
            if (!string.IsNullOrEmpty(str) && int.TryParse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out i)) {
                using (s.destBitmap) {
                    s.destBitmap = new RedEyeFilter((short)i).Apply(s.destBitmap);
                }
                //Note to future self: sobel/canny/eye kernel convolutions were not helpful; they were dead ends.
             }
            return RequestedAction.None;
        }
Esempio n. 17
0
        /// <summary>
        /// Supporting rounded corners.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        protected override RequestedAction PreRenderImage(ImageState s)
        {
            if (s.sourceBitmap == null) return RequestedAction.None;
            double[] vals = NameValueCollectionExtensions.GetList<double>(s.settings, "s.roundcorners",0,1,4);
            if (vals == null) return RequestedAction.None;

            if (vals.Length == 1)  vals = new double[]{vals[0],vals[0],vals[0],vals[0]};

            bool hasValue = false;
            foreach (double d in vals) if (d > 0) hasValue = true;
            if (!hasValue) return RequestedAction.None;

            Bitmap cropped = null;
            try{
                //Make sure cropping is applied, and use existing prerendered bitmap if present.
                s.ApplyCropping();

                cropped = s.preRenderBitmap ?? s.sourceBitmap;

                s.preRenderBitmap = new Bitmap(cropped.Width,cropped.Height, PixelFormat.Format32bppArgb);

                int[] radius = new int[4];
                //Radius percentages are 0-100, a percentage of the smaller of the width and height.
                for (int i = 0; i < vals.Length; i++) radius[i] = (int)Math.Round(Math.Max(0,Math.Min(99.999,vals[i])) * ((double)Math.Min(s.preRenderBitmap.Width,s.preRenderBitmap.Height) / 100));

                s.preRenderBitmap.MakeTransparent();
                using (Graphics g = Graphics.FromImage(s.preRenderBitmap)) {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.CompositingMode = CompositingMode.SourceOver;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    using (TextureBrush tb = new TextureBrush(cropped))
                    using (GraphicsPath gp = new GraphicsPath(FillMode.Winding)) {
                        Rectangle bounds = new Rectangle(0, 0, s.preRenderBitmap.Width, s.preRenderBitmap.Height);
                        int[] angles = new int[]{180,270,0,90};
                        int[] xs = new int[]{bounds.X,bounds.Right - radius[1], bounds.Right - radius[2], bounds.X};
                        int[] ys = new int[]{bounds.Y,bounds.Y,bounds.Bottom - radius[2], bounds.Bottom - radius[3]};
                        for (int i =0; i < 4; i++){
                            if (radius[i] > 0){
                                gp.AddArc(xs[i],ys[i],radius[i],radius[i],angles[i],90);
                            }else{
                                gp.AddLine(xs[i],ys[i],xs[i],ys[i]);
                            }
                        }
                        g.FillPath(tb, gp);

                    }
                }
            }finally{
                if (cropped != null & cropped != s.sourceBitmap) cropped.Dispose();
            }
            return RequestedAction.None;
        }
Esempio n. 18
0
        /// <summary>
        /// Creates a bitmap of s.destSize dimensions, intializes a graphics object for it, and configures all the default settings.
        /// </summary>
        /// <param name="s"></param>
        protected override RequestedAction PrepareDestinationBitmap(ImageState s)
        {
            if (base.PrepareDestinationBitmap(s) == RequestedAction.Cancel) return RequestedAction.Cancel;

             if (s.sourceBitmap == null) return RequestedAction.None;

            //Create new bitmap using calculated size.
            s.destBitmap = new Bitmap(s.destSize.Width,s.destSize.Height, PixelFormat.Format32bppArgb);

            //Create graphics handle
            Graphics g = s.destGraphics = Graphics.FromImage(s.destBitmap);

            //High quality everthing
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.CompositingMode = CompositingMode.SourceOver;
            return RequestedAction.None;
        }
Esempio n. 19
0
 protected override RequestedAction LayoutRound(ImageState s)
 {
     if (base.LayoutRound(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions
     //Todo, round points here.
     //s.layout.Round();
     return RequestedAction.None;
 }
Esempio n. 20
0
 protected override RequestedAction LayoutRotate(ImageState s)
 {
     if (base.LayoutRotate(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions
     //Now, rotate all rings.
     s.layout.Rotate(s.settings.Rotate, new PointF(0, 0));
     return RequestedAction.None;
 }
Esempio n. 21
0
        protected override RequestedAction LayoutPadding(ImageState s)
        {
            if (base.LayoutPadding(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions

            //We need to add padding
            if (!s.settings.Padding.IsEmpty) {
                s.layout.AddRing("padding",  s.settings.Padding);
            }
            return RequestedAction.None;
        }
Esempio n. 22
0
        protected RequestedAction RenderLayersForLevel(ImageState s, Layer.LayerPlacement only)
        {
            string watermark = s.settings["watermark"]; //from the querystring
            Graphics g = s.destGraphics;
            if (string.IsNullOrEmpty(watermark) || g == null) return RequestedAction.None;

            string[] parts = watermark.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            bool foundPart = false;

            foreach (string w in parts) {
                if (NamedWatermarks.ContainsKey(w)) {
                    IEnumerable<Layer> layers = NamedWatermarks[w];
                    foreach (Layer l in layers) {
                        if (l.DrawAs == only) {
                            l.RenderTo(s);
                        }
                    }
                    foundPart = true;
                }
            }
            if ( !foundPart && only == Layer.LayerPlacement.Overlay) {
                //Parse named watermark files

                if (watermark.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) > -1 ||
                    watermark.IndexOfAny(new char[] { '\\', '/' }) > -1)
                    throw new ArgumentException("Watermark value contained invalid file name characters: " + watermark);

                if (OtherImages != null && OtherImages.Path != null) {
                    ImageLayer layer = OtherImages.Copy();

                    //Is the watermark dir a physical path?
                    char slash = layer.Path.Contains("/") ? '/' : '\\';
                    layer.Path = layer.Path.TrimEnd(slash) + slash + watermark.TrimStart(slash);

                    //If it's a forward-slash, and we're in asp.net,  verify the file exists
                    if (slash == '/' && HttpContext.Current != null && !c.Pipeline.FileExists(layer.Path, layer.ImageQuery)) return RequestedAction.None;
                    layer.RenderTo(s);

                } else {
                    this.LegacyDrawWatermark(s);
                }
            }
            return RequestedAction.None;
        }
Esempio n. 23
0
        protected override RequestedAction PostRenderImage(ImageState s)
        {
            Color? c = Util.ParseUtils.ParseColor(s.settings["s.overlay"]);

            if (c != null && s.destGraphics != null) {
                using (var b = new SolidBrush(c.Value)) {
                    s.destGraphics.FillPolygon(b, s.layout["image"]);
                }
            }
            return RequestedAction.None;
        }
Esempio n. 24
0
        public LayoutInformation(ImageState state)
        {
            this.instructions = new NameValueCollection(state.settings);

            this.sourceRect = new SizeOnly(state.originalSize);
            this.finalRect = new SizeOnly(state.destSize);

            this.imageSourcePoly = new PolyRect(state.copyRect);

            if (state.layout.ContainsRing("image"))
            {
                this.imageDestPoly = new PolyRect(state.layout["image"]);
            }

            if (state.layout.ContainsRing("imageArea"))
            {
                this.imageDestAreaPoly = new PolyRect(state.layout["imageArea"]);
            }

            // Check to see if sFlip/sRotate has altered the original raw image
            // rectangle.  The check must be the same as in
            // ImageBuilder.PrepareSourceBitmap().  Note that the adjustment
            // happens only when there's an actual bitmap, regardless of the
            // sFlip/sRotate settings.
            if (state.sourceBitmap != null &&
                (state.settings.SourceFlip != RotateFlipType.RotateNoneFlipNone ||
                !string.IsNullOrEmpty(state.settings["sRotate"])))
            {
                // We need to calculate the original rect/poly by *reversing* the
                // requested sFlip/sRotate.  We determine what the requested change
                // was, then calculate the reverse.
                var angle = state.settings.Get<double>("sRotate", 0);
                var flipRotate = (int)PolygonMath.CombineFlipAndRotate(state.settings.SourceFlip, angle);
                var copyPoly = PolygonMath.ToPoly(state.copyRect);
                var trueOriginalSize = state.originalSize;

                // The RotateFlipType values are ordered such that odd values
                // transpose the size of the rectangle, %4 gives the rotation
                // and /4 (=> 0 or 1) whether there's been an x-flip.  We can
                // use this to streamline our calculations.
                if (flipRotate % 2 == 1)
                {
                    trueOriginalSize = new Size(state.originalSize.Height, state.originalSize.Width);
                }

                this.preAdjustedSourceRect = new SizeOnly(trueOriginalSize);

                // Remember that the sFlip/sRotate change performed the rotation
                // first and then the flip, so we have to do the opposite to go
                // backwards.
                if (flipRotate / 4 == 1)
                {
                    copyPoly = PolygonMath.ScalePoints(copyPoly, -1, 1, PointF.Empty);
                    copyPoly = PolygonMath.MovePoly(copyPoly, new PointF(trueOriginalSize.Width, 0));
                }

                // It's possible to calculate a rotation-origin that will place
                // the original pre-sRotate (0,0) point back at (0,0) again...
                // but since it involves sqrt(), there would be rounding errors
                // that we should be able to avoid.  (We might, in fact, want to
                // avoid using PolygonMath entirely, and hand-map the points
                // backwards for accuracy.)
                switch (flipRotate % 4)
                {
                    case 0: // no rotation
                        // no-op!
                        break;

                    case 1: // 90 degrees, clockwise
                        copyPoly = PolygonMath.RotatePoly(copyPoly, -90);
                        copyPoly = PolygonMath.MovePoly(copyPoly, new PointF(0, trueOriginalSize.Height));
                        break;

                    case 2: // 180 degrees, clockwise
                        copyPoly = PolygonMath.RotatePoly(copyPoly, -180);
                        copyPoly = PolygonMath.MovePoly(copyPoly, new PointF(trueOriginalSize.Width, trueOriginalSize.Height));
                        break;

                    case 3: // 270 degrees, clockwise
                        copyPoly = PolygonMath.RotatePoly(copyPoly, -270);
                        copyPoly = PolygonMath.MovePoly(copyPoly, new PointF(trueOriginalSize.Width, 0));
                        break;
                }

                this.preAdjustedImageSourcePoly = new PolyRect(copyPoly);
            }
        }
Esempio n. 25
0
        protected override RequestedAction PostCreateImageAttributes(ImageState s)
        {
            if (s.copyAttibutes == null) return RequestedAction.None;

            if (!s.settings.WasOneSpecified((string[])GetSupportedQuerystringKeys())) return RequestedAction.None;

            List<float[][]> filters = new List<float[][]>();

            string filter = s.settings["filter"];
            if (!string.IsNullOrEmpty(filter)) {
                int valuesStart = filter.IndexOf('(');
                string valStr = null;
                double[] values = null;
                if (valuesStart > -1) {
                    valStr = filter.Substring(valuesStart);
                    filter = filter.Substring(0, valuesStart);
                    values = ParseUtils.ParseList<double>(valStr, 0,0,1);
                }

                if ("grayscale".Equals(filter, StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleFlat());
                if ("sepia".Equals(filter, StringComparison.OrdinalIgnoreCase)) filters.Add(Sepia());
                if (values != null && values.Length == 1) {
                    if ("alpha".Equals(filter, StringComparison.OrdinalIgnoreCase)) filters.Add(Alpha((float)values[0]));
                    if ("brightness".Equals(filter, StringComparison.OrdinalIgnoreCase)) filters.Add(Brightness((float)values[0]));
                }
            }
            if ("true".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleNTSC());
            if ("flat".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleFlat());
            if ("y".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleY());
            if ("ry".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleRY());
            if ("ntsc".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleNTSC());
            if ("bt709".Equals(s.settings["s.grayscale"], StringComparison.OrdinalIgnoreCase)) filters.Add(GrayscaleBT709());

            if ("true".Equals(s.settings["s.sepia"], StringComparison.OrdinalIgnoreCase)) filters.Add(Sepia());
            if ("true".Equals(s.settings["s.invert"], StringComparison.OrdinalIgnoreCase)) filters.Add(Invert());

            Color? c = Util.ParseUtils.ParseColor(s.settings["s.shift"]);

            if (c != null) filters.Add(Shift(c.Value));

            string alpha = s.settings["s.alpha"];
            string brightness = s.settings["s.brightness"];
            string contrast = s.settings["s.contrast"];
            string saturation = s.settings["s.saturation"];

            double temp = 0;
            if (!string.IsNullOrEmpty(alpha) && double.TryParse(alpha, ParseUtils.FloatingPointStyle, NumberFormatInfo.InvariantInfo, out temp)) filters.Add(Alpha((float)temp));
            if (!string.IsNullOrEmpty(brightness) && double.TryParse(brightness, ParseUtils.FloatingPointStyle, NumberFormatInfo.InvariantInfo, out temp)) filters.Add(Brightness((float)temp));
            if (!string.IsNullOrEmpty(contrast) && double.TryParse(contrast, ParseUtils.FloatingPointStyle, NumberFormatInfo.InvariantInfo, out temp)) filters.Add(Contrast((float)temp));
            if (!string.IsNullOrEmpty(saturation) && double.TryParse(saturation, ParseUtils.FloatingPointStyle, NumberFormatInfo.InvariantInfo, out temp)) filters.Add(Saturation((float)temp));

            if (filters.Count == 0) return RequestedAction.None;
            if (filters.Count == 1) s.copyAttibutes.SetColorMatrix(new ColorMatrix(filters[0]));
            else {
                //Multiple all the filters
                float[][] first = filters[0];

                for (int i = 1; i < filters.Count; i++) {
                    first = Multiply(first, filters[i]);
                }
                s.copyAttibutes.SetColorMatrix(new ColorMatrix(first));

            }

            return RequestedAction.None;
        }
Esempio n. 26
0
        protected override RequestedAction LayoutBorder(ImageState s)
        {
            if (base.LayoutBorder(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions

            //And borders
            if (!s.settings.Border.IsEmpty) {
                s.layout.AddRing("border", s.settings.Border);
            }
            return RequestedAction.None;
        }
Esempio n. 27
0
 protected override RequestedAction PostRenderBackground(ImageState s)
 {
     return RenderLayersForLevel(s, Layer.LayerPlacement.Background);
 }
Esempio n. 28
0
        /// <summary>
        /// Populates copyRect, as well as Rings image and imageArea. Translates and scales any existing rings as if they existed on the original bitmap.
        /// </summary>
        /// <param name="s"></param>
        protected override RequestedAction LayoutImage(ImageState s)
        {
            if (base.LayoutImage(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions

            if (s.copyRect.IsEmpty) {
                //Use the crop size if present.
                s.copyRect = new RectangleF(new PointF(0, 0), s.originalSize);
                if (NameValueCollectionExtensions.GetList<double>(s.settings, "crop", 0, 4) != null) {
                    s.copyRect = PolygonMath.ToRectangle(s.settings.getCustomCropSourceRect(s.originalSize)); //Round the custom crop rectangle coordinates
                    if (s.copyRect.Size.IsEmpty) throw new Exception("You must specify a custom crop rectange if crop=custom");
                }
            }
            //Save the manual crop size.
            SizeF manualCropSize = s.copySize;
            RectangleF manualCropRect = s.copyRect;

            FitMode fit = s.settings.Mode;
            //Determine fit mode to use if both vertical and horizontal limits are used.
            if (fit == FitMode.None){
                if (s.settings.Width != -1 || s.settings.Height != -1){

                    if ("fill".Equals(s.settings["stretch"], StringComparison.OrdinalIgnoreCase)) fit = FitMode.Stretch;
                    else if ("auto".Equals(s.settings["crop"], StringComparison.OrdinalIgnoreCase)) fit = FitMode.Crop;
                    else if (!string.IsNullOrEmpty(s.settings["carve"])
                        && !"false".Equals(s.settings["carve"], StringComparison.OrdinalIgnoreCase)
                        && !"none".Equals(s.settings["carve"], StringComparison.OrdinalIgnoreCase)) fit = FitMode.Carve;
                    else fit = FitMode.Pad;
                }else{
                    fit = FitMode.Max;
                }

            }

            //Aspect ratio of the image
            double imageRatio = s.copySize.Width / s.copySize.Height;

            //Zoom factor
            double zoom = s.settings.Get<double>("zoom", 1);

            //The target size for the image
            SizeF targetSize = new SizeF(-1, -1);
            //Target area for the image
            SizeF areaSize = new SizeF(-1, -1);
            //If any dimensions are specified, calculate. Otherwise, use original image dimensions
            if (s.settings.Width != -1 || s.settings.Height != -1 || s.settings.MaxHeight != -1 || s.settings.MaxWidth != -1) {
                //A dimension was specified.
                //We first calculate the largest size the image can be under the width/height/maxwidth/maxheight restrictions.
                //- pretending stretch=fill and scale=both

                //Temp vars - results stored in targetSize and areaSize
                double width = s.settings.Width;
                double height = s.settings.Height;
                double maxwidth = s.settings.MaxWidth;
                double maxheight = s.settings.MaxHeight;

                //Eliminate cases where both a value and a max value are specified: use the smaller value for the width/height
                if (maxwidth > 0 && width > 0) {   width = Math.Min(maxwidth, width);    maxwidth = -1;  }
                if (maxheight > 0 && height > 0) { height = Math.Min(maxheight, height); maxheight = -1; }

                //Handle cases of width/maxheight and height/maxwidth as in legacy versions.
                if (width != -1 && maxheight != -1) maxheight = Math.Min(maxheight, (width / imageRatio));
                if (height != -1 && maxwidth != -1) maxwidth = Math.Min(maxwidth, (height * imageRatio));

                //Move max values to width/height. FitMode should already reflect the mode we are using, and we've already resolved mixed modes above.
                width = Math.Max(width, maxwidth);
                height = Math.Max(height, maxheight);

                //Calculate missing value (a missing value is handled the same everywhere).
                if (width > 0 && height <= 0) height = width/ imageRatio;
                else if (height > 0 && width <= 0) width = height * imageRatio;

                //We now have width & height, our target size. It will only be a different aspect ratio from the image if both 'width' and 'height' are specified.

                //FitMode.Max
                if (fit == FitMode.Max) {
                    areaSize = targetSize = PolygonMath.ScaleInside(manualCropSize, new SizeF((float)width, (float)height));
                //FitMode.Pad
                } else if (fit == FitMode.Pad) {
                    areaSize = new SizeF((float)width, (float)height);
                    targetSize = PolygonMath.ScaleInside(manualCropSize, areaSize);
                //FitMode.crop
                } else if (fit == FitMode.Crop) {
                    //We autocrop - so both target and area match the requested size
                    areaSize = targetSize = new SizeF((float)width, (float)height);
                    RectangleF copyRect;

                    ScaleMode scale = s.settings.Scale;
                    bool cropWidthSmaller = manualCropSize.Width <= (float)width;
                    bool cropHeightSmaller = manualCropSize.Height <= (float)height;

                    // With both DownscaleOnly (where only one dimension is smaller than
                    // requested) and UpscaleCanvas, we will have a targetSize based on the
                    // minWidth & minHeight.
                    // TODO: what happens if mode=crop;scale=down but the target is larger than the source?
                    if ((scale == ScaleMode.DownscaleOnly && (cropWidthSmaller != cropHeightSmaller)) ||
                        (scale == ScaleMode.UpscaleCanvas))
                    {
                        var minWidth = Math.Min(manualCropSize.Width, (float)width);
                        var minHeight = Math.Min(manualCropSize.Height, (float)height);

                        targetSize = new SizeF(minWidth, minHeight);
                        copyRect = manualCropRect = new RectangleF(0, 0, minWidth, minHeight);

                        // For DownscaleOnly, the areaSize is adjusted to the new targetSize as well.
                        if (scale == ScaleMode.DownscaleOnly)
                        {
                            areaSize = targetSize;
                        }
                    }
                    else
                    {
                        //Determine the size of the area we are copying
                        Size sourceSize = PolygonMath.RoundPoints(PolygonMath.ScaleInside(areaSize, manualCropSize));
                        //Center the portion we are copying within the manualCropSize
                        copyRect = new RectangleF(0, 0, sourceSize.Width, sourceSize.Height);
                    }

                    // Align the actual source-copy rectangle inside the available
                    // space based on the anchor.
                    s.copyRect = PolygonMath.ToRectangle(PolygonMath.AlignWith(copyRect, s.copyRect, s.settings.Anchor));

                } else { //Stretch and carve both act like stretching, so do that:
                    areaSize = targetSize = new SizeF((float)width, (float)height);
                }

            }else{
                //No dimensions specified, no fit mode needed. Use manual crop dimensions
                areaSize = targetSize = manualCropSize;
            }

            //Multiply both areaSize and targetSize by zoom.
            areaSize.Width *= (float)zoom;
            areaSize.Height *= (float)zoom;
            targetSize.Width *= (float)zoom;
            targetSize.Height *= (float)zoom;

            //Todo: automatic crop is permitted to break the scaling rules. Fix!!

            //Now do upscale/downscale checks. If they take effect, set targetSize to imageSize
            if (s.settings.Scale == ScaleMode.DownscaleOnly) {
                if (PolygonMath.FitsInside(manualCropSize, targetSize)) {
                    //The image is smaller or equal to its target polygon. Use original image coordinates instead.
                    areaSize = targetSize = manualCropSize;
                    s.copyRect = manualCropRect;
                }
            } else if (s.settings.Scale == ScaleMode.UpscaleOnly) {
                if (!PolygonMath.FitsInside(manualCropSize, targetSize)) {
                    //The image is larger than its target. Use original image coordintes instead
                    areaSize = targetSize = manualCropSize;
                    s.copyRect = manualCropRect;
                }
            } else if (s.settings.Scale == ScaleMode.UpscaleCanvas) {
                //Same as downscaleonly, except areaSize isn't changed.
                if (PolygonMath.FitsInside(manualCropSize, targetSize)) {
                    //The image is smaller or equal to its target polygon.

                    //Use manual copy rect/size instead.

                    targetSize = manualCropSize;
                    s.copyRect = manualCropRect;
                }
            }

            //May 12: require max dimension and round values to minimize rounding differences later.
            areaSize.Width = Math.Max(1, (float)Math.Round(areaSize.Width));
            areaSize.Height = Math.Max(1, (float)Math.Round(areaSize.Height));
            targetSize.Width = Math.Max(1, (float)Math.Round(targetSize.Width));
            targetSize.Height = Math.Max(1, (float)Math.Round(targetSize.Height));

            //Translate and scale all existing rings
            s.layout.Shift(s.copyRect, new RectangleF(new Point(0, 0), targetSize));

            s.layout.AddRing("image", PolygonMath.ToPoly(new RectangleF(new PointF(0, 0), targetSize)));

            s.layout.AddRing("imageArea",PolygonMath.ToPoly(new RectangleF(new PointF(0, 0), areaSize)));

            //Center imageArea around 'image'
            s.layout["imageArea"] = PolygonMath.AlignWith(s.layout["imageArea"], s.layout["image"], s.settings.Anchor);

            return RequestedAction.None;
        }
Esempio n. 29
0
 protected override RequestedAction RenderOverlays(ImageState s)
 {
     return RenderLayersForLevel(s, Layer.LayerPlacement.Overlay);
 }
Esempio n. 30
0
 protected override RequestedAction LayoutNormalize(ImageState s)
 {
     if (base.LayoutNormalize(s) == RequestedAction.Cancel) return RequestedAction.Cancel; //Call extensions
     //Normalize all the rings
     s.layout.Normalize(new PointF(0, 0));
     return RequestedAction.None;
 }