Граница метки при использовании ключа прозрачности

#c# #winforms

#c# #winforms

Вопрос:

У меня есть winform (с ключом прозрачности), чтобы сделать его прозрачным. Но когда я добавляю метку, я получаю эту границу «fushia» вокруг метки. Я знаю, что это связано с тем, что для элемента управления нет «установленного» фона. Но есть ли способ удалить эту «границу».

Для формы задано значение background Fuchsia (ключ прозрачности Fuchsia), а для метки задано значение transparent. Попытался нарисовать его на панели с теми же результатами.

Чего мне не хватает?

Как это выглядит, http://oi62.tinypic.com/2wq9z7c.jpg

 public class CLabel : Label
{
    protected override CreateParams CreateParams { get { CreateParams parms = base.CreateParams; parms.ExStyle |= 0x20; return parms; } }

    public CLabel()
    {
        this.SetStyle(ControlStyles.Opaque, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // null
    }

     GraphicsPath GetStringPath(RectangleF rect, StringFormat format)
    {
        GraphicsPath Path = new GraphicsPath();

        Path.AddString(this.Text, this.Font.FontFamily, (int)Font.Style, this.Font.Size, rect, format);
        return Path;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        RectangleF rect = this.ClientRectangle;
        Font font = this.Font;
        StringFormat format = StringFormat.GenericDefau<

        using (GraphicsPath path = GetStringPath(rect, format))
        {
            SmoothingMode sm = e.Graphics.SmoothingMode;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            Brush b = new SolidBrush(Color.White);
            e.Graphics.FillPath(b, path);
            e.Graphics.DrawPath(Pens.Black, path);

            b.Dispose();
        }
    }
}

public partial class Dy : Form
{
  protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; cp.ExStyle |= 0x80; return cp; } }

    public Dy()
    {
        InitializeComponent();

        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.DoubleBuffer, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        this.StartPosition = FormStartPosition.Manual;

        // Here I add the label
        CLabel p = new CLabel{ 
            Location = new Point(768, 702),
            Text = "25",
            AutoSize = false, 
            Size = new Size(50,50), 
            TextAlign = ContentAlignment.MiddleCenter, 
            BackColor = Color.Transparent, 
            ForeColor = Color.White, 
            BorderStyle = BorderStyle.None, 
            Font = new Font("Segoe UI", 30, FontStyle.Bold)
        };
 }
}
 

Комментарии:

1. Я предполагаю, что это приложение Windows Forms. Вы не должны заставлять нас предполагать. Вместо этого вы должны добавить тег [WinForms].

Ответ №1:

Похоже на артефакты сглаживания.

Вы можете попытаться изменить

 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
 

Для

 e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
 

или вы можете полностью отключить сглаживание:

 e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
 

Редактировать: я убрал это из комментариев, так как это может помочь некоторым людям:

Вот немного больше об артефактах AA..

AA всегда будет создавать пиксели, которые интерполируют, и это всегда будет приводить к пикселям, которые несколько пропускают цвет ключа прозрачности.

Очевидно, что они исчезают, только если не используется AA; но если действительно нужно сгладить, этот маленький трюк может помочь улучшить результат:

Обычно TransparencyKey выполняется с помощью грубого цвета, такого как Fuchsia или HotPink . Они используются редко, поэтому они вряд ли прорежут отверстия, но когда они просвечивают через полупрозрачный пиксель формата АА, они неприятны. Если вы используете менее раздражающий цвет, этот эффект может стать незаметным.

Вам просто нужно убедиться, что вы не используете его в другом месте. Выберите цвет, Color.FromArgb(255, r,g,b) выбрав 3 уникальных значения, которые вы не будете использовать в другом месте, но которые сочетаются как с передним планом, так и, что более важно, с фоном. Вероятно, поможет очень низкая насыщенность и, в зависимости от вашей графики, средняя яркость..

Black или нейтральный серый цвет не являются хорошим выбором, даже если они хорошо сочетаются, потому что они используются так часто. Но выбор, например, чего-то почти черного, такого как ARGB (255, 7, 11, 5), также имеет хорошие шансы смешаться, не будучи использованным в графике и вырезая отверстия в выходных данных.

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

Комментарии:

1. Хорошо. Любопытно: достаточно ли было TextRenderingHint или вам нужно было установить SmoothingMode? Также: если вы довольны, пожалуйста, примите ответ!

2. Да, этого было достаточно, чтобы просто изменить TextRendering. Но я наткнулся на другую проблему при попытке добавить границу к метке. Как только я отключаю AA, он работает, но как только я снова включаю его, я снова получаю этот фон. Не уверен, знаете ли вы, как это исправить, не страдая от действительно плохого качества при отключении AA. * Обновлено текущим кодом

3. AA всегда будет создавать пиксели, которые интерполируются. Это всегда будет приводить к пикселям, которые несколько пропускают цвет ключа traparency. Боюсь, что обойти это невозможно.

4. Ну ладно. Есть ли способ обойти это? Сделайте это растровым изображением или, может быть, используйте OpenGL? Пытался пометить его как принятый, но он продолжает возвращаться назад.

5. Хорошо, спасибо за помощь 🙂 Просто попробовал с черным, и он работает с отступом (но мне нужно найти лучший цвет). Я попытаюсь решить эту проблему как решаемую, но никогда раньше не сталкивался с этой «ошибкой»: P