Была поставлена задача прикрутить антиалиасинг для выполнения графических операций в приложении написанном на языке C# с использованием платформы .NET Compact Framework 3.5.
Решение:
Поскольку в Compact Framework нет поддержки антиалиасинга, было принято решение выполнять рисование с использованием функций GDI+, которые поддерживают этот режим.
Как вызывать функции GDI+ из приложения, написанного на платформе Compact Framework написано в статье "Using GDI+ on Windows Mobile": http://community.opennetcf.com/articles/cf/archive/2007/10/31/using-gdi-on-windows-mobile.aspx
Для того чтобы включить режим антиалиасинга перед выполнением функции рисования какого-либо графического примитива вызывается функция GDI+ SetSmoothingMode() с параметром SmoothingModeAntiAlias.
Если выполнять рисование следующим образом то все работает, но при перерисовке видно постоянное мерцание.
protected override void OnPaint(PaintEventArgs e)
{
Graphics objGraphics = e.Graphics;
//Далее идет получение контекста устройства
IntPtr hdc = objGraphics.GetHdc();
//Рисование средствами GDI+
// (код не приводится потому что используется куча оберточных классов и структур и приводить все это здесь не имеет смысла)
...
}
Результат выглядит таким образом что края линий ровные, видно применение эффекта антиалиасинга:
Чтобы мерцания не было рисование в приложении выполняется следующим образом:
protected override void OnPaint(PaintEventArgs e)
{
//Создание изображения в памяти
Image objImage = new Bitmap(Width, Heigth);
//Получение объекта класса Graphics от изображения в памяти
Graphics objGraphics = Graphics.FromImage(objImage);
//Далее все то же самое: получение контекста устройства и выполнение рисования функциями GDI+
IntPtr hdc = objGraphics.GetHdc();
...
//Копирование изображения из памяти на экран
e.Graphics.DrawImage(objImage, 0, 0);
}
В результате получаем искаженный эффект антиалиасинга, когда по краям линий видна черная полоса и края линий остаются зубчатыми.
У кого-нибудь есть мысли из-за чего получается такой эффект и как его можно избежать?
В чем разница между рисованием напрямую с использованием контекста устройства и рисованием с предварительным созданием изображения в памяти, которое в последствии копируется в основной контекст устройства?
Заранее благодарен.
27.03.11 10:18: Перенесено модератором из '.NET' — TK
Re: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
Здравствуйте, SAdventurer, Вы писали:
SA>У кого-нибудь есть мысли из-за чего получается такой эффект и как его можно избежать?
я бы проверил, что SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias во всех Graphics которые используются (включая тот, который получен FromImage).
кстати, от мерцания на WinForms я избавлялся с помощью свойства DoubleBuffered. В CF такого нет?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
Здравствуйте, Neco, Вы писали:
N>я бы проверил, что SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias во всех Graphics которые используются (включая тот, который получен FromImage).
Этого я сделать не могу, в Compact Framework такого свойства нету, я из объекта Graphics получаю только конекст устройства, с которым потом работают функции GDI+:
IntPtr hdc = objGraphics.GetHdc();
N>кстати, от мерцания на WinForms я избавлялся с помощью свойства DoubleBuffered. В CF такого нет?
В CF такого нет.
Re: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
Еще одна мысль появилась: на другой форме где производится рисование изображения с использованием двойной буферизации и device dependent bitmap которая создается функцией CreateCompatibleBitmap() библиотеки Gdi32.dll все работает, возможно нужно искать решение проблемы в этом направлении.
Re: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
Здравствуйте, midcyber, Вы писали:
M>Возможно, в обычном graphics фон залит прозрачным цветом, а в изображении, созданном NewBitmap — черным?
Пробовал вызывать функцию Graphics.Clear() с различными цветами, включая Transparent — не помогает.
Под дебагером также заметил что в объекте Graphics приходящем в событии OnPaint свойство PageUnit стоит в значении Pixel, тогда как в объекте Graphics полученном от созданного битмапа оно стоит в значении Display. Хотя этого свойства даже нет в CF в классе Graphics. Попробовал его задать перед рисованием через вызов функции GDI+ GdipSetPageUnit() — тоже никакого эффекта.
Вполне возможно в объектах Graphics отличаются еще какие-нибудь свойства, значения которых даже не выводятся дебагером, но они стоят в различных значениях, надо только догадатсья какие? . Вопрос заключается в том какие еще свойства могут влиять на рисование, тогда можно будет задать их через функции GDI+.