Эффект внешнего свечения для текста C#

я хочу иметь текст внешнего свечения в метке для моего приложения winform, например:

я искал его в stackoverflow и нашел это:

private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

{

  //Create a bitmap in a fixed ratio to the original drawing area.

  Bitmap bm=new Bitmap(this.ClientSize.Width/5, this.ClientSize.Height/5);

  //Create a GraphicsPath object. 

  GraphicsPath pth=new GraphicsPath();

  //Add the string in the chosen style. 

  pth.AddString("Text Halo",new FontFamily("Verdana"),(int)FontStyle.Regular,100,new Point(20,20),StringFormat.GenericTypographic);

  //Get the graphics object for the image. 

  Graphics g=Graphics.FromImage(bm);

  //Create a matrix that shrinks the drawing output by the fixed ratio. 

  Matrix mx=new Matrix(1.0f/5,0,0,1.0f/5,-(1.0f/5),-(1.0f/5));

  //Choose an appropriate smoothing mode for the halo. 

  g.SmoothingMode=SmoothingMode.AntiAlias;

  //Transform the graphics object so that the same half may be used for both halo and text output. 

  g.Transform=mx;

  //Using a suitable pen...

  Pen p=new Pen(Color.Yellow,3);

  //Draw around the outline of the path

  g.DrawPath(p,pth);

  //and then fill in for good measure. 

  g.FillPath(Brushes.Yellow,pth);

  //We no longer need this graphics object

  g.Dispose();

  //this just shifts the effect a little bit so that the edge isn't cut off in the demonstration

  e.Graphics.Transform=new Matrix(1,0,0,1,50,50);

  //setup the smoothing mode for path drawing

  e.Graphics.SmoothingMode=SmoothingMode.AntiAlias;

  //and the interpolation mode for the expansion of the halo bitmap

  e.Graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;

  //expand the halo making the edges nice and fuzzy. 

  e.Graphics.DrawImage(bm,ClientRectangle,0,0,bm.Width,bm.Height,GraphicsUnit.Pixel);

  //Redraw the original text

  e.Graphics.FillPath(Brushes.Black,pth);

  //and you're done. 

  pth.Dispose();

}

но проблема в том, что я не могу переместить его, пожалуйста, помогите мне, мне нужно, чтобы он был подвижным, и я хочу иметь возможность изменять его размер. приведенный выше код просто автоматически добавляет его куда-то в мою форму, но я хочу его переместить. Спасибо

Возможно, это может сработать Перемещение элементов управления в форме во время выполнения

Karen Payne 28.10.2022 11:37

код находится в событии рисования формы, а не в событии других элементов управления, на самом деле он добавит строку в клиентскую область формы, но я не могу правильно изменить положение (я хочу сказать, где и какой размер шрифта)

CleverWolf 28.10.2022 11:59

@CleverWolf Пожалуйста, используйте последнюю версию. Содержит несколько важных исправлений. Смотрите комментарии к моему ответу.

dr.null 29.10.2022 09:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
153
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Лучшим подходом является создание пользовательского элемента управления для использования/добавления некоторых соответствующих свойств чертежа. Главным образом, Шрифт и цвет текста, размер и цвет контура. Затем вы можете разместить пользовательский элемент управления в любом контейнере в любом месте и любого размера.

Вот простой пример.

[DesignerCategory("Code")]
public class GlowTextLabel : Control
{
    private Color outlineColor = SystemColors.Highlight;
    private int outlineSize = 1;

    public GlowTextLabel() : base()
    {
        SetStyle(ControlStyles.Selectable, false);
        SetStyle(ControlStyles.OptimizedDoubleBuffer |
            ControlStyles.ResizeRedraw |
            ControlStyles.SupportsTransparentBackColor, true);
    }

    [DefaultValue(typeof(Color), "Highlight")]
    public Color OutlineColor
    {
        get => outlineColor;
        set
        {
            if (outlineColor != value)
            {
                outlineColor = value;
                Invalidate();
            }
        }
    }
        
    [DefaultValue(1)]
    public int OutlineSize
    {
        get => outlineSize;
        set
        {
            if (outlineSize != value)
            {
                outlineSize = Math.Max(1, value);
                Invalidate();
            }
        }
    }

    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.Clear(BackColor);

        var w = Math.Max(8, ClientSize.Width / 5);
        var h = Math.Max(8, ClientSize.Height / 5);

        using (var bmp = new Bitmap(w, h))
        using (var gp = new GraphicsPath())
        using (var sf = new StringFormat(StringFormat.GenericTypographic))
        {
            sf.Alignment = sf.LineAlignment = StringAlignment.Center;

            gp.AddString(Text, 
                Font.FontFamily, (int)Font.Style, GetEmFontSize(Font), 
                ClientRectangle, sf);
               
            using (var g = Graphics.FromImage(bmp))
            using (var m = new Matrix(1.0f / 5, 0, 0, 1.0f / 5, -(1.0f / 5), -(1.0f / 5)))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.Transform = m;

                using (var pn = new Pen(OutlineColor, OutlineSize))
                {
                    g.DrawPath(pn, gp);
                    g.FillPath(pn.Brush, gp);
                }
            }

            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            // Optional for wider blur...
            // e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
            e.Graphics.DrawImage(bmp, 
                ClientRectangle, 0, 0, bmp.Width, bmp.Height, 
                GraphicsUnit.Pixel);
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            using (var br = new SolidBrush(ForeColor))
                e.Graphics.FillPath(br, gp);
        }
    }
}

private float GetEmFontSize(Font fnt) =>
    fnt.SizeInPoints * (fnt.FontFamily.GetCellAscent(fnt.Style) +
    fnt.FontFamily.GetCellDescent(fnt.Style)) / fnt.FontFamily.GetEmHeight(fnt.Style);

Перестройте, найдите элемент управления GlowTextLabel на панели инструментов в группе компонентов вашего проекта, отбросьте экземпляр, попробуйте свойства Font, ForeColor, OutlineColor и OutlineSize с разными значениями.

Ширина пера 1.

Ширина пера 10.

Ширина пера 20.

Большое спасибо, это сработало для меня! Я работаю над изменением цвета фона с черного на прозрачный.

CleverWolf 29.10.2022 05:23

@Jimi Jimziii, убийца кода! Доброе утро/день. У меня еще нет InitializeComponent() мозгов. Однако я кое-что нашел и исправил. Если что-то еще, отредактируйте или скажите что. Перестань дразнить меня :) . Часть из этого, попробуйте с gp.Widen(pn); причудливым результатом.

dr.null 29.10.2022 07:58

Думаю, с gp.Widen(new Pen(Color.White, OutlineSize / 3.25f)); немного лучше. Можно установить как вариант :) (конечно, вы избавитесь от пера позже) -- Что касается проблемы (которая огромна), у вас БЫЛО это: using (var sf = StringFormat.GenericTypographic) {...} (сейчас частично исправлено) => поскольку StringFormat.GenericTypographic есть static, вы изменяли рендеринг всего кода, который его использует, для всего приложения. Правильная форма будет using (var sf = new StringFormat(StringFormat.GenericTypographic)), чтобы было удобно использовать предустановленные

Jimi 29.10.2022 08:30

@ Джими Согласен, это было важно. Что касается других улучшений, пожалуйста, оставьте комментарии, чтобы ОП и будущие читатели приняли их во внимание. Спасибо, Джим, и никому не говорите :)

dr.null 29.10.2022 08:47

Другие вопросы по теме