Сглаженный текст на прозрачном растровом изображении
Я хотел бы нарисовать сглаженный текст на прозрачном растровом изображении и сделать сглаживание в виде альфа-смешанных пикселей. Таким образом, я могу нарисовать растровое изображение на любой цветовой поверхности (или, если на то пошло, изображение), и сглаживание по-прежнему выглядит нормально.
Вот упрощенный пример, показывающий проблему:
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));
}
И вот результат:
http://img194.imageshack.us/img194/9065/captureotd.png
Конечная цель этого - использовать UpdateLayeredWindow для рисования моего прозрачного альфа-смешанного окна. Я создаю приложение, похожее на Conky, и я хотел бы иметь возможность использовать рендеринг ClearType для текста (это легко без сглаживания, конечно).
В настоящее время я беру экран за форму, рисую его, а затем рисую свой текст. Это выглядит хорошо, но должно быть обновлено и медленно рисовать. Любые другие идеи для рисования текста на рабочем столе также приветствуются.
2 ответа
Ваш текст отображается как есть, потому что у вас включен режим сглаживания субпикселей ClearType (по умолчанию в Vista и выше). ClearType, по определению, не может хорошо играть с альфа-каналом, поскольку он смешивает цвета и, следовательно, не зависит от фона. Таким образом, он игнорирует альфа-канал и смешивается с черным (в противном случае это ваш прозрачный цвет). Вам нужно включить сглаживание в оттенках серого для достижения желаемого эффекта:
g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
Я не уверен, действительно ли это необходимо, но если вы хотите сделать альфа-смешивание, вы должны указать 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));
Делаете ли вы то, что хотите, или просто скрываете проблему?