winforms C# winform中的文本阴影

iqxoj9l9  于 2022-11-17  发布在  C#
关注(0)|答案(4)|浏览(394)

如何在winform中在文本上放置阴影。特别是在位图对象上绘制文本。我知道我们可以用深色来绘制文本,并将其放置到正确的位置,使其像阴影一样。但这个阴影看起来很纤细和坚实。我希望它更宽和模糊。我发现了一些可以模糊和成像的函数。但当我应用到我的情况时,它会把透明区域变成黑色。2请给予我一个指引。

ezykj2lf

ezykj2lf1#

作为渲染模糊阴影的替代方法,一个性能更友好的选项可能是渲染阴影稍微向右下方偏移(如您最初建议的那样),但使用 * alpha透明度 *,以便阴影看起来不那么“实心”:

protected void RenderDropshadowText(
    Graphics graphics, string text, Font font, Color foreground, Color shadow, 
    int shadowAlpha, PointF location)
{
    const int DISTANCE = 2;
    for (int offset = 1; 0 <= offset; offset--)
    {
        Color color = ((offset < 1) ? 
            foreground : Color.FromArgb(shadowAlpha, shadow));
        using (var brush = new SolidBrush(color))
        {
            var point = new PointF()
            {
                X = location.X + (offset * DISTANCE),
                Y = location.Y + (offset * DISTANCE)
            };
            graphics.DrawString(text, font, brush, point);
        }
    }
}

要给予如何从代码(如OnPaint方法)中调用它的示例,请执行以下操作:

RenderDropshadowText(e.Graphics, "Dropshadow Text", 
    this.Font, Color.MidnightBlue, Color.DimGray, 64, new PointF(10, 10));

为了让事情变得更整洁,并获得更令人信服的阴影效果,我们可以修改上面的函数,通过稍微增加alpha透明度来绘制文本,一次在阴影的左边,一次稍微在阴影的右边,来模拟模糊效果:

if (offset > 0)
{
    using (var blurBrush = new SolidBrush(Color.FromArgb((shadowAlpha / 2), color)))
    {
        graphics.DrawString(text, font, blurBrush, (point.X + 1), point.Y);
        graphics.DrawString(text, font, blurBrush, (point.X - 1), point.Y);
    }
}

下面是生成的输出的屏幕截图:

dy2hfwbg

dy2hfwbg2#

可以尝试使用Path(如果可以从文本中生成路径?)和PathGradientBrush

using (PathGradientBrush brush = new PathGradientBrush(pathShadow))
        {
            ColorBlend blend = new ColorBlend();
            blend.Colors = new Color[] { Color.Transparent, Color.Black };
            blend.Positions = new float[] { 0.0f, 1.0f };
            brush.InterpolationColors = blend;
            graph.FillPath(brush, pathShadow);
        }

或者你可以尝试对叠加图像做一些事情(这只是一个想法,这里有一个由path定义的发光物体的例子):

// inside OnPaint
        // overlay
        using (Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb))
        {
            using (Graphics gtemp = Graphics.FromImage(bmp))
            {
                // fake glowing
                using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, Color.FromArgb(200, 255, 255, 255), Color.FromArgb(0, 0, 0, 0), LinearGradientMode.Vertical))
                {
                    brush.SetBlendTriangularShape(0.5f, 1.0f);
                    gtemp.FillPath(brush, path);
                }
                // draw on screen
                e.Graphics.DrawImage(bmp, 0, 0);
            }
        }
vjrehmav

vjrehmav3#

下面是创建阴影的WinForms Label控件的一个非常简化的实现:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace MyCustom.Controls
{
    public class ShadowLabel : Label
    {
        #region Properties
        protected int _xOffset = 5;
        protected int _yOffset = 5;
        #endregion

        #region Constructor
        public ShadowLabel() : base() => InitializeComponent();
        #endregion

        #region Accessors
        /// <summary>Specifies the solid-colour value of the shadow. No alpha information from this setting is used.</summary>
        /// <remarks>Alpha blending is handled programmatically via the <i>Alpha</i> accessor value.</remarks>
        /// <seealso cref="Alpha"/>
        public Color ShadowColor { get; set; } = Color.Black;

        /// <summary>Specifies the vertical translation of the shadow (up/down). Range: -25 to +25.</summary>
        /// <remarks>Using a negative value shifts the shadow up, while a positive value shifts downwards.</remarks>
        public int xOffset
        {
            get => this._xOffset;
            set => this._xOffset = (value < 0) ? Math.Max(value,-25) : Math.Min( 25, value );
        }

        /// <summary>Specifies the horizontal translation of the shadow (left/right). Range: -25 to +25.</summary>
        /// <remarks>Using a negative value shifts the shadow left, while a positive value goes right.</remarks>
        public int yOffset
        {
            get => this._yOffset;
            set => this._yOffset = (value < 0) ? Math.Max( value, -25 ) : Math.Min( 25, value );
        }

        /// <summary>Specifies the starting Alpha value of the shadow (how solid is it).</summary>
        /// <remarks>The shadow is made more transparent as it deepens, from this value to zero.</remarks>
        public byte Alpha { get; set; } = 255;
        #endregion

        #region Methods
        protected override void OnPaint( PaintEventArgs e )
        {
            Graphics g = e.Graphics;
         
            int xStart = Math.Min( this.Location.X, this.Location.X + xOffset ),
                xEnd = Math.Max( this.Location.X, this.Location.X + xOffset ),
                yStart = Math.Min( this.Location.Y, this.Location.Y + yOffset ),
                yEnd = Math.Max( this.Location.Y, this.Location.Y + yOffset ),
                steps, xIncrement, yIncrement, alphaIncrement;
        
            steps = Math.Max( xEnd - xStart, yEnd - yStart );
            xIncrement = ( xOffset  < 0 ? -1 : 1 ) * (int)Math.Floor( (xEnd - xStart) / (float)steps );
            yIncrement = ( yOffset  < 0 ? -1 : 1 ) * (int)Math.Floor( (yEnd - yStart) / (float)steps );
            alphaIncrement = (int)Math.Floor( Alpha / (float)steps );

            if ( steps > 0 )
            {
                for ( int i = steps; i > 0; i-- )
                    g.DrawString(
                        this.Text,
                        this.Font,
                        new SolidBrush(
                                Color.FromArgb(
                                    this.Alpha - (alphaIncrement * i),
                                    ShadowColor.R,
                                    ShadowColor.G,
                                    ShadowColor.B
                                )
                            ),
                            new PointF()
                            {
                                X = (xIncrement * i), // this.Location.X + (xIncrement * i), 
                                Y = (yIncrement * i)  // this.Location.Y + (yIncrement * i) 
                            }
                        );

                g.DrawString( this.Text, this.Font, new SolidBrush( this.ForeColor ), new PointF( 0f, 0f ) );
            }
            else base.OnPaint( e );
        }
        #endregion

        /// <summary>Required designer variable.</summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>Clean up any resources being used.</summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose( bool disposing )
        {
            if ( disposing && (components != null) )
                components.Dispose();

            base.Dispose( disposing );
        }

        #region Component Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent() =>
            components = new System.ComponentModel.Container();
        #endregion
    }
}
1tu0hz3e

1tu0hz3e4#

我知道这个答案可能一点帮助都没有,但是如果它只是静态文本,就用图像代替

相关问题