Example #1
0
        /// <summary>
        /// Draws text with a border.
        /// </summary>
        /// <param name="gfx">The source graphics object</param>
        /// <param name="text">The text to render</param>
        /// <param name="font">The font to render</param>
        /// <param name="brush">The brush to use for the rendered text</param>
        /// <param name="x">The x location to render the text at</param>
        /// <param name="y">The y location to render the text at</param>
        /// <param name="border">The width of the border to render in pixels</param>
        /// <param name="borderColors">A collection of colors to border should cycle through</param>
        /// <param name="colorOffsets">An index-matching collection of offsets to render the border colors at</param>
        public static void DrawString(this Graphics gfx, string text, Font font, Brush brush, int x, int y, int border, Color[] borderColors, float[] colorOffsets)
        {
            if (string.IsNullOrWhiteSpace(text))
                return;
            if (gfx == null)
                throw new ArgumentNullException("gfx");
            if (font == null)
                throw new ArgumentNullException("font");
            if (brush == null)
                throw new ArgumentNullException("brush");
            if (border <= 0)
                throw new ArgumentException("Border must be greater than 0", "border");
            if (borderColors.Length == 0)
                throw new ArgumentException("Border requires at least 1 color", "borderColors");
            if (borderColors.Length > 1 && borderColors.Length != colorOffsets.Length)
                throw new ArgumentException("A border with more than 1 color requires a matching number of offsets", "colorOffsets");
            if (colorOffsets == null || colorOffsets.Length == 0)
                colorOffsets = new[] {(float)0};

            // Organize color fades from inner to outer
            var colors = borderColors
                .Select((c, i) => new KeyValuePair<float, Color>(colorOffsets[i], c))
                .OrderBy(c => c.Key)
                .ToArray();
            // Get bordered boundaries
            var offset = gfx.MeasureStringBoundaries(text, font).Location;
            var measure = gfx.MeasureStringBoundaries(text, font, border);

            using (var workImage = new Bitmap((int)measure.Width, (int)measure.Height))
            using (var gfxWork = Graphics.FromImage(workImage))
            {
                gfxWork.PageUnit = GraphicsUnit.Point;
                gfxWork.SmoothingMode = gfx.SmoothingMode;
                var path = new GraphicsPath();
                path.AddString(text, font.FontFamily, (int) font.Style, font.Size, new PointF((border-offset.X)*(float).75, (border-offset.Y)*(float).75), StringFormat.GenericDefault);

                // Fade the border from outer to inner.
                for (var b = border; b > 0; b--)
                {
                    var colorIndex = (float) 1/border*b;
                    var colorStart = colors.Length > 1 ? colors.Last(c => c.Key <= colorIndex) : colors.First();
                    var colorEnd = colors.Length > 1 ? colors.First(c => c.Key >= colorIndex) : colors.First();
                    var colorOffset = 1/Math.Max((float).0000001, colorEnd.Key - colorStart.Key)*(colorIndex - colorStart.Key);
                    var color = colorStart.Value.FadeTo(colorEnd.Value, colorOffset);

                    const float lineWidthOffset = (float) .65; // This is approximate
                    using (var pen = new Pen(color, b/lineWidthOffset) { LineJoin = LineJoin.Round })
                        gfxWork.DrawPath(pen, path);
                }

                // Draw the text
                gfxWork.FillPath(brush, path);
                var bounds = workImage.DetectPadding();
                var offsetX = ((measure.Width - bounds.Right) - bounds.X)/2;

                // Apply the generated image
                gfx.DrawImage(workImage, x + offsetX, y);
            }
        }
Example #2
0
        private void button1_Click(object sender, EventArgs e)
        {
            var dlg = new OpenFileDialog { Title = "Please select an image to open:", Filter = "Jpeg|*.jpg|Jpeg|*.jpeg|Png|*.png|Bitmap|*.bmp" };
            if (dlg.ShowDialog() != DialogResult.OK)
                return;

            var img = Image.FromFile(dlg.FileName);

            // Scale to fit
            _scaleToFit.BackgroundImage = img.ScaleToFit(_scaleToFit.Size, false);

            // Scale to fit (overflow)
            _scaleToOverflow.BackgroundImage = img.ScaleToFit(_scaleToOverflow.Size, false, ScalingMode.Overflow);

            // Stretch to fit
            _stretch.BackgroundImage = img.Stretch(_stretch.Size, false);

            // Rotate and fit
            _rotateFit.BackgroundImage = img.ScaleToFit(_rotateFit.Size, false).Rotate(45, ScalingMode.FitContent).ScaleToFit(_rotateOverflow.Size);
            
            // Rotate and overflow
            _rotateOverflow.BackgroundImage = img.ScaleToFit(_rotateOverflow.Size, false).Rotate(45);

            // Fast pixel manipulation (UnsafeContext)
            _pixelManipulation.BackgroundImage = img.ScaleToFit(_pixelManipulation.Size, false);
            using (var context = _pixelManipulation.BackgroundImage.CreateUnsafeContext())
            {
                for (var y = 0; y < context.Height; y++)
                    for (var x = 0; x < context.Width; x++)
                    {
                        var pixel = context.GetRawPixel(x, y);
                        var level = Math.Max(pixel.Red, Math.Max(pixel.Green, pixel.Blue));
                        context.SetPixel(x, y, pixel.Alpha, level, level, level);
                    }
            }
            _pixelManipulation.Refresh();

            // Detect Edges
            var edge = new Bitmap(_edgeDetection.Width, _edgeDetection.Height);
            using (var gfx = Graphics.FromImage(edge))
            {
                gfx.DrawEllipse(Pens.Black, 25, 25, 50, 50);
                var bounds = edge.DetectPadding();
                gfx.DrawLine(Pens.Red, bounds.Left, 0, bounds.Left, edge.Height);
                gfx.DrawLine(Pens.Red, bounds.Right, 0, bounds.Right, edge.Height);
                gfx.DrawLine(Pens.Red, 0, bounds.Top, edge.Width, bounds.Top);
                gfx.DrawLine(Pens.Red, 0, bounds.Bottom, edge.Width, bounds.Bottom);
            }
            _edgeDetection.BackgroundImage = edge;

            // Create animated Gif
            var gifImage = img.ScaleToFit(_gifGeneration.Size, false);
            var gifStream = new MemoryStream(); // NOTE: Disposing this stream will break this demo - I don't know why.
            using (var encoder = new GifEncoder(gifStream))
                for (var angle = 0; angle < 360; angle += 10)
                    using (var frame = gifImage.Rotate(angle, false))
                    {
                        encoder.AddFrame(frame, 0, 0, TimeSpan.FromSeconds(0));
                    }
            gifStream.Position = 0;
            _gifGeneration.Image = Image.FromStream(gifStream);

            // Draw text with effects
            _textGen.BackgroundImage = img.ScaleToFit(_textGen.Size, false, ScalingMode.Overflow);
            using (var gfx = Graphics.FromImage(_textGen.BackgroundImage))
            {
                gfx.DrawString("A B C 1 2 3", new Font(FontFamily.Families.First(f => f.Name.Contains("Times")), 15), Brushes.Green, 15, 25, 10,
                    new[] {Color.Yellow, Color.Blue, Color.Red, Color.Green, Color.Purple, Color.Black},
                    new[] { 0, (float).20, (float).40, (float).60, (float).80, 1 });
            }
        }