예제 #1
0
        /// <summary>
        /// Returns a rectangle representing the given ring - if it is an axis-parallel rectangle. Otherwise returns null;
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public RectangleF?GetRingAsRectF(string name)
        {
            var poly  = this[name];
            var rect  = PolygonMath.GetBoundingBox(poly);
            var poly2 = PolygonMath.ToPoly(rect);

            return(PolygonMath.ArraysEqual(poly, poly2) ? (RectangleF?)rect : null);
        }
예제 #2
0
        protected virtual void AssertLayout(string sourceSize, string resizeSettings, Action <RectangleF> assertImage, Action <SizeF> assertCanvas)
        {
            var sourceSizeSettings = new ResizeSettings(sourceSize);
            var result             = _imageLayoutBuilder.BuildLayout(new Size(sourceSizeSettings.Width, sourceSizeSettings.Height), new ResizeSettings(resizeSettings));

            if (assertCanvas != null)
            {
                assertCanvas(result.CanvasSize);
            }
            if (assertImage != null)
            {
                assertImage(result.Image);
            }

            var maxWidth  = (int)(Math.Max(result.Image.Width, result.CanvasSize.Width));
            var maxHeight = (int)(Math.Max(result.Image.Height, result.CanvasSize.Height));

            var padding = (int)Math.Max(Math.Abs(result.Image.Y), Math.Abs(result.Image.X)) + 20;

            if ((maxWidth + padding) < 400)
            {
                padding = (400 - maxWidth) / 2;
            }

            // create a bitmap for visualizing
            var bitmapSize = new RectangleF(0, 0, maxWidth + padding * 2, maxHeight + (padding * 2));

            using (var bmp = new Bitmap((int)bitmapSize.Width, (int)bitmapSize.Height))
            {
                using (var gfx = Graphics.FromImage(bmp))
                {
                    // set the background
                    gfx.FillRectangle(new SolidBrush(Color.White), 0, 0, bmp.Width, bmp.Height);

                    // output the results
                    gfx.DrawString("Source: " + sourceSize, new Font("Thaoma", 8), Brushes.Black, new RectangleF(0, 0, bmp.Width, bmp.Height), new StringFormat {
                        Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near
                    });
                    gfx.DrawString("Destination: " + resizeSettings, new Font("Thaoma", 8), Brushes.Black, new RectangleF(0, 0, bmp.Width, bmp.Height), new StringFormat {
                        Alignment = StringAlignment.Far, LineAlignment = StringAlignment.Near
                    });
                    gfx.DrawString("Canvas: " + result.CanvasSize.Width + "x" + result.CanvasSize.Height, new Font("Thaoma", 8), Brushes.Green, new RectangleF(0, 0, bmp.Width, bmp.Height), new StringFormat {
                        Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Far
                    });
                    gfx.DrawString("Image: " + result.Image.Width + "x" + result.Image.Height, new Font("Thaoma", 8), Brushes.Red, new RectangleF(0, 0, bmp.Width, bmp.Height), new StringFormat {
                        Alignment = StringAlignment.Far, LineAlignment = StringAlignment.Far
                    });

                    //PolygonMath.AlignWith()
                    var canvas = new RectangleF(padding, padding, result.CanvasSize.Width, result.CanvasSize.Height);
                    var image  = new RectangleF(padding + result.Image.X, padding + result.Image.Y, result.Image.Width, result.Image.Height);
                    var points = new List <PointF>();
                    points.AddRange(PolygonMath.ToPoly(canvas));
                    points.AddRange(PolygonMath.ToPoly(image));
                    points = PolygonMath.AlignWith(points.ToArray(), PolygonMath.ToPoly(bitmapSize), ContentAlignment.MiddleCenter).ToList();
                    canvas = PolygonMath.GetBoundingBox(points.Take(4).ToArray());
                    image  = PolygonMath.GetBoundingBox(points.Skip(4).Take(4).ToArray());
                    gfx.FillRectangle(new SolidBrush(Color.Green), canvas);
                    gfx.DrawRectangle(new Pen(Color.Red, 2), image.X, image.Y, image.Width, image.Height);
                }
                var fileName = sourceSize + "--" + resizeSettings + ".bmp";
                var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                bmp.Save(filePath, ImageFormat.Bmp);

                Trace.WriteLine("Source:        " + sourceSize);
                Trace.WriteLine("Destination:   " + resizeSettings);
                Trace.WriteLine("   Result:     " + filePath);
            }
        }
예제 #3
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);
            }
        }
예제 #4
0
        public override void RenderTo(Resizing.ImageState s)
        {
            if (string.IsNullOrEmpty(Text))
            {
                return;
            }

            string finalText = Text;

            if (finalText.IndexOf('#') > -1)
            {
                Regex r = new Regex("\\#\\{([^}]+)\\}");
                finalText = r.Replace(finalText, delegate(Match m){
                    string val = s.settings[m.Groups[1].Value];
                    if (val == null)
                    {
                        return("");
                    }
                    else
                    {
                        return(val);
                    }
                });
            }

            SizeF      naturalSize   = SizeF.Empty;
            SizeF      unrotatedSize = SizeF.Empty;
            RectangleF bounds        = this.CalculateLayerCoordinates(s, delegate(double maxwidth, double maxheight) {
                using (Font f = GetFont())
                    using (StringFormat sf = GetFormat()){
                        naturalSize = s.destGraphics.MeasureString(finalText, f, new PointF(), sf);
                        SizeF size  = naturalSize;

                        unrotatedSize = Fill ? PolygonMath.ScaleInside(size, new SizeF((float)maxwidth, (float)maxheight)) : size;

                        if (Angle != 0)
                        {
                            size = PolygonMath.GetBoundingBox(PolygonMath.RotatePoly(PolygonMath.ToPoly(new RectangleF(new PointF(0, 0), size)), Angle)).Size;
                        }
                        if (Fill)
                        {
                            size = PolygonMath.ScaleInside(size, new SizeF((float)maxwidth, (float)maxheight));
                        }
                        f.FontFamily.Dispose();
                        return(PolygonMath.RoundPoints(size));
                    }
            }, true);

            using (Font f = GetFont()) {
                s.destGraphics.SmoothingMode      = SmoothingMode.HighQuality;
                s.destGraphics.TextRenderingHint  = Rendering; // Utils.parseEnum<TextRenderingHint>(s.settings["watermark.rendering"], this.Rendering); ;
                s.destGraphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                s.destGraphics.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                s.destGraphics.CompositingMode    = CompositingMode.SourceOver;
                s.destGraphics.CompositingQuality = CompositingQuality.HighQuality;

                s.destGraphics.ResetTransform();
                if (Angle != 0)
                {
                    s.destGraphics.RotateTransform((float)Angle);
                }
                s.destGraphics.ScaleTransform(unrotatedSize.Width / naturalSize.Width, unrotatedSize.Height / naturalSize.Height);
                s.destGraphics.TranslateTransform(bounds.X, bounds.Y, MatrixOrder.Append);
                using (StringFormat sf = GetFormat()) {
                    DrawString(s.destGraphics, finalText, f, new Point(0, 0), sf);
                }
                s.destGraphics.ResetTransform();

                f.FontFamily.Dispose();
            }
        }