c#. Не меняется alpha-параметр цвета в Graphics.DrawString

197
10 декабря 2017, 09:08

Добрый день!

Пытаюсь с помощью c# нарисовать полупрозрачный текст. Пишу следующий код:

Bitmap bm = new Bitmap(250, 250);
Graphics gr = Graphics.FromImage(bm);
clr = Color.FromArgb(50, 0, 0, 0);
font = new Font("Times New Roman", 70);
gr.DrawString("test", font, new SolidBrush(clr), 0, 0);

Все удаётся.

Но если установить размер текста 65 или ниже, то прозрачность исчезает.

Есть у кого идеи почему так происходит и что с этим делать?

Спасибо.

Answer 1

Судя по проведенным экспериментам и раскопкам в доступных исходниках, ошибка где-то в нативных методах GDI.

Воспроизводится только при получении объекта Graphics из Bitmap и , возможно (не проверял), других наследников Image, при вызове Graphics.DrawString. В моем случае граничными размерами шрифта оказались 67+ (прозрачность используется) и 66- (прозрачность игнорируется).

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

При использовании объекта Graphics, полученного из аргументов события Control.Paint, проблемы не наблюдается при любых размерах шрифта.

Точной ответ на вопрос "почему?" видимо можно получить только у авторов, т.к. код нативных методов GDI закрыт.

А вот способ обойти проблему есть, хоть и не очень красивый. Если нужен прозрачный текст именно на Bitmap, то нужно сделать следующее:

  • Создаем объект GraphicsPath
  • С помощью метода GraphicsPath.AddString пишем текст.
  • С помощью метода Graphics.FillPath рисуем закрашенный объект GraphicsPath на Bitmap.

В результате ожидаемая прозрачность сохраняется при любых размерах текста. Подробности работы с объектом GraphicsPath с примерами кода есть на MSDN.

Должен предупредить, что размер, который указывается в GraphicsPath.AddString не совпадает с размером, который указывается в параметре конструктора Font, поэтому размер придется подбирать с учетом новых условий.

В качестве альтернативного способа, можно рисовать прозрачный текст сразу на контроле/форме, если такой вариант применим в вашем случае.

READ ALSO
Вычисление суммы ряда на С#

Вычисление суммы ряда на С#

Вычислить сумму ряда с заданной точностью eps

220
Взаимодействие между двумя и более ViewModel

Взаимодействие между двумя и более ViewModel

Доброго времени суток, ГосподаПрошу помочь мне в моем спаггети-коде и разложить все по полочкам

243
Таймаут в фуллскрин моде между кликом на экране pause/play и даблкликом на экране - выход из фуллскрина

Таймаут в фуллскрин моде между кликом на экране pause/play и даблкликом на экране - выход из фуллскрина

Приветствую, хотел спросить: как тут сделать чтобы был таймаут между кликами по экрану - play/pause и даблкликом fullscreen ибо когда видео проигрывается...

288