Сглаженный текст на прозрачном растровом изображении

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

Вот упрощенный образец, показывающий проблему:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Bitmap bitmap = new Bitmap(this.Width, this.Height);
    Graphics g = Graphics.FromImage(bitmap);
    g.Clear(Color.Empty);
    g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));
    e.Graphics.DrawImage(bitmap, new Point(0, 0));
}

И вот результат:

альтернативный текст

Конечная цель этого - использовать UpdateLayeredWindow для рисования моего прозрачного окна с альфа-смешиванием. Я создаю приложение, подобное Conky, и я хотел бы иметь возможность использовать ClearType для визуализации текста (это, конечно, легко без сглаживания).

В настоящее время я беру экран за формой, рисую его, а затем рисую свой текст. Выглядит неплохо, но требует обновления и медленно отрисовывается. Также приветствуются любые другие идеи по рисованию текста на рабочем столе.


person iano    schedule 17.08.2009    source источник


Ответы (2)


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

g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
person Pavel Minaev    schedule 18.08.2009
comment
Это сработало, спасибо! Это не так красиво, как ClearType, но даже шрифты, разработанные для ClearType (например, Consolas), по-прежнему выглядят нормально. - person iano; 18.08.2009
comment
Любопытно, что для меня AntiAliasGridFit выдает текст без сглаживания. AntiAlias, однако, работает. - person Roman Starkov; 26.12.2011
comment
AntiAliasGridFit может не выполнять сглаживание, если размер шрифта слишком мал. При таком размере шрифта AntiAlias все равно дает ужасный результат. - person Francis Gagné; 09.07.2013

Я не уверен, действительно ли это необходимо, но если вы хотите выполнить альфа-смешивание, вы должны указать 32-битное изображение:

Bitmap bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

Используя ваш пример, я смог придать тексту достойный вид, добавив подсказку для рендеринга текста:

g.Clear(Color.Empty);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("hello world", new Font(this.Font.FontFamily, 24), Brushes.Blue, new Point(50, 50));

Вы делаете то, что хотите, или просто скрываете проблему?

person Tim Sylvester    schedule 18.08.2009
comment
Если вы опустите PixelFormat Bitmap, по умолчанию все равно будет Format32bppArgb. - person Pavel Minaev; 18.08.2009
comment
Загадочным образом ваш код TextRenderingHint.AntiAlias вместо TextRenderingHint.AntiAliasGridFit работает как шарм! Спасибо - person γηράσκω δ' αεί πο; 12.01.2019