Вопрос или проблема
Я пытаюсь использовать шрифт в пиксельном стиле для написания текста на растровом изображении в WinForm. Шрифт, который я использую, это: https://font.download/font/pocket-pixel.
Я хочу, чтобы текст был очень маленьким (6pt) и идеальным в пикселях, без сглаживания, но при рисовании текста на растровом изображении он не соответствует шрифту.
При использовании шрифта в программном обеспечении для редактирования изображений (в моем случае Paint.NET) я устанавливаю размер на 6 pt, и результат идеален.
Когда я продолжаю и использую тот же шрифт для рисования текста на растровом изображении в WinForm, результат как маленький, так и испорченный, даже при больших размерах шрифта.
У меня есть как шаблон растрового изображения, так и файл шрифта, встроенный в ресурсы. Это фрагмент кода:
public class Class1
{
private static PrivateFontCollection fonts = new PrivateFontCollection();
static FontFamily LoadFontResource(byte[] fontData)
{
IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
uint dummy = 0;
fonts.AddMemoryFont(fontPtr, fontData.Length);
AddFontMemResourceEx(fontPtr, (uint)fontData.Length, IntPtr.Zero, ref dummy);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
return fonts.Families.Last();
}
public Bitmap GetBitmap()
{
var bmp = new Bitmap(Resources.template);
FontFamily PocketPixel_FontFamily = LoadFontResource(Resources.pokemon_pixel_font);
Font PocketPixel_Font = new Font(PocketPixel_FontFamily, 12, GraphicsUnit.Pixel);
using (Graphics graphics = Graphics.FromImage(bmp))
{
Brush brush = Brushes.Black;
StringFormat format = new StringFormat
{
Alignment = StringAlignment.Center, // Выравнивание по центру
LineAlignment = StringAlignment.Near
};
// Отключить сглаживание
graphics.SmoothingMode = SmoothingMode.None;
graphics.PixelOffsetMode = PixelOffsetMode.None;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
graphics.PageUnit = GraphicsUnit.Pixel;
graphics.PageScale = 1f;
// Рисуем текст
RectangleF area = new RectangleF(20, 145, 100, 10);
graphics.DrawString("1234567890", PocketPixel_Font, brush, area, format);
}
return bmp;
}
public SavePng()
{
var bmp = GetBitmap();
bmp.Save("WhyYouNoWork.png", ImageFormat.Png);
}
}
Как вы видите, я пытался изменить несколько свойств объекта Graphics или самого объекта Font, чтобы достичь желаемого результата, но без успеха.
Есть ли какие-нибудь предложения (Пожалуйста, проголосуйте за картинки)?
Спасибо
Ответ или решение
Проблема с отрисовкой пиксельного шрифта в WinForm: Решение
Когда речь заходит о пиксельных шрифтах, таких как используемый вами Pocket Pixel, важно понимать, что они требуют очень точной настройки в графическом контексте, чтобы выглядеть корректно. Давайте рассмотрим несколько важных аспектов, которые могут помочь вам исправить проблему с отрисовкой текста на битмапе в WinForms.
1. Загрузка шрифта
Ваш код правильно загружает шрифт из ресурса, и этот шаг не вызывает вопросов. Однако важно убедиться, что файл шрифта действительно загружается корректно. Если загружаемый шрифт повреждён или несовместим, это может повлиять на его отображение. Проверьте, работает ли шрифт, используя его в других приложениях, чтобы убедиться в его исправности.
2. Настройка параметров Graphics
Отрисовка текстов с использованием пиксельных шрифтов требует отключения сглаживания, но вы также можете изменить параметры PixelOffsetMode
и TextRenderingHint
, чтобы обеспечить более точное отображение. Попробуйте следующие значения:
graphics.SmoothingMode = SmoothingMode.None;
graphics.PixelOffsetMode = PixelOffsetMode.Half; // Измените на Half
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; // Оставьте для пиксельных шрифтов
Хотя PixelOffsetMode.None
может показаться правильным выбором, для пиксельной отрисовки PixelOffsetMode.Half
может обеспечить более точное соответствие пикселям.
3. Правильные размеры шрифта
Хотя вы хотите использовать шрифт размером 6 pt, результат может различаться из-за DPI (точек на дюйм) выставленного в вашем приложении. В Windows размер шрифта в точках основан на DPI и может отличаться от ожидаемого. Попробуйте задать размер в пикселях, например 8 или 12, и адаптируйте его в зависимости от визуального результата. Кроме того, используйте параметры GraphicsUnit.Pixel
и узнайте, какое разрешение у вашего битмапа.
4. Проверка целостности битмапа
Перед тем как отрисовывать текст, убедитесь, что ваш битмап создан с правильными параметрами, такими как DPI. Например:
var bmp = new Bitmap(Resources.template);
bmp.SetResolution(96f, 96f); // Установка DPI для соответствия точкам
5. Отрисовка текста в нужной области
Убедитесь, что прямоугольник для отрисовки текста имеет правильные размеры и позиции. Попробуйте изменить размеры RectangleF
, чтобы убедиться, что текст полностью помещается в выделенной области.
6. Финальные шаги
Совмещая все вышеизложенные рекомендации, итоговый фрагмент вашего кода может выглядеть следующим образом:
graphics.SmoothingMode = SmoothingMode.None;
graphics.PixelOffsetMode = PixelOffsetMode.Half;
graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
// Пример улучшенного размера шрифта
Font PocketPixel_Font = new Font(PocketPixel_FontFamily, 8, FontStyle.Regular, GraphicsUnit.Pixel);
Заключение
Для достижения "пиксельной точности" при использовании пиксельных шрифтов в WinForms как никогда важно учитывать параметры отрисовки, разрешение и правильные размеры шрифта. Применяя предложенные выше советы, вы на правильном пути к исправлению проблемы и принятию во внимание всех аспектов отрисовки текста. Если после всех изменений проблема все еще сохраняется, вероятно, стоит проверить другие графические библиотеки или методы отрисовки.