Anti aliasing функциями GDI+ на платформе .NET CF 3.5
От: SAdventurer Россия  
Дата: 25.03.11 08:32
Оценка:
Проблема:

Была поставлена задача прикрутить антиалиасинг для выполнения графических операций в приложении написанном на языке 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
От: Neco  
Дата: 25.03.11 13:00
Оценка:
Здравствуйте, SAdventurer, Вы писали:

SA>У кого-нибудь есть мысли из-за чего получается такой эффект и как его можно избежать?

я бы проверил, что SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias во всех Graphics которые используются (включая тот, который получен FromImage).

кстати, от мерцания на WinForms я избавлялся с помощью свойства DoubleBuffered. В CF такого нет?
всю ночь не ем, весь день не сплю — устаю
Re[2]: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
От: SAdventurer Россия  
Дата: 25.03.11 13:12
Оценка:
Здравствуйте, 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
От: SAdventurer Россия  
Дата: 25.03.11 13:39
Оценка:
Нашел вот ссылку, где описывается подобная проблема:
How to enable anti-aliased drawing of text on a Graphics-object created by Graphics.FromImage()
http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/968edd29-35bc-4bef-a8b3-bc2745ce8109/

Код приводится на VB, мне это правда не помогло, но предлагаемое решение:

Removing "Imaging.PixelFormat.Format32bppRgb" from my constructor solved all the problems

For future reference to other people having the same problem, changed my constructor to:


Dim bBufferBitmap As Bitmap = New Bitmap(lWidth, lHeight)
Dim gBufferGraphics As Graphics = Graphics.FromImage(bBufferBitmap)



Перепробовал все варианты параметра PixelFormat, их в CF не так много, изменений не увидел:

public enum PixelFormat
{
        Format16bppRgb555 = 135173,
        Format16bppRgb565 = 135174,
        Format24bppRgb = 137224,
        Format32bppRgb = 139273,
}


Еще одна мысль появилась: на другой форме где производится рисование изображения с использованием двойной буферизации и device dependent bitmap которая создается функцией CreateCompatibleBitmap() библиотеки Gdi32.dll все работает, возможно нужно искать решение проблемы в этом направлении.
Re: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
От: midcyber
Дата: 25.03.11 16:51
Оценка:
Здравствуйте, SAdventurer, Вы писали:

SA>У кого-нибудь есть мысли из-за чего получается такой эффект и как его можно избежать?


Возможно, в обычном graphics фон залит прозрачным цветом, а в изображении, созданном NewBitmap — черным?
Re[2]: Anti aliasing функциями GDI+ на платформе .NET CF 3.5
От: SAdventurer Россия  
Дата: 28.03.11 07:02
Оценка:
Здравствуйте, midcyber, Вы писали:

M>Возможно, в обычном graphics фон залит прозрачным цветом, а в изображении, созданном NewBitmap — черным?


Пробовал вызывать функцию Graphics.Clear() с различными цветами, включая Transparent — не помогает.

Под дебагером также заметил что в объекте Graphics приходящем в событии OnPaint свойство PageUnit стоит в значении Pixel, тогда как в объекте Graphics полученном от созданного битмапа оно стоит в значении Display. Хотя этого свойства даже нет в CF в классе Graphics. Попробовал его задать перед рисованием через вызов функции GDI+ GdipSetPageUnit() — тоже никакого эффекта.
Вполне возможно в объектах Graphics отличаются еще какие-нибудь свойства, значения которых даже не выводятся дебагером, но они стоят в различных значениях, надо только догадатсья какие? . Вопрос заключается в том какие еще свойства могут влиять на рисование, тогда можно будет задать их через функции GDI+.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.