Правила большого пальца в GDI+
Я работал над кодом GDI+ в.NET и усердно изучал свои уроки. Простые вещи, такие как:
- То, что хорошо выглядит на экране, на бумаге может выглядеть не очень хорошо, и наоборот
- Кэширование слишком большого количества объектов может привести к исключению OutOfMemoryException
- Поплавки не точны
...и так далее. Я уверен, что опытные люди могут добавить к этому гораздо больше.
Какие правила следует соблюдать при использовании GDI+ или любой графической библиотеки в целом?
Один полезный совет за пост будет хорошим. Благодарю.
7 ответов
Создавайте объекты как можно позже (не преждевременно оптимизируйте / кэшируйте) и освобождайте их как можно раньше (вызывая Dispose или добавляя оператор using, если IDisposable).
Не избегайте неуправляемых звонков, это может значительно ускорить процесс, если все сделано правильно.
Не рисуй больше, чем нужно.
В общем, операции рисования обходятся дороже, чем другие вычисления, которые вы будете выполнять (особенно в GDI+, который является хорошим API, но не самой быстрой библиотекой рисования когда-либо). Тратить немного больше времени на собственный код, чтобы избежать ненужных операций рисования (например, рисование одной и той же вещи более одного раза), часто того стоит.
Осторожнее при преобразовании между логическими / экранными координатами. Если вы сделали не в то время, вы можете потерять точность и получить взамен некоторые неприятные артефакты рисования.
В прошлый раз, когда меня это кусало, я пытался вычислить новую точку в логических координатах; хотя они были уже близки к пределу точности, поэтому новая точка была не совсем тем, на что можно было бы надеяться. Трансформер скорее исправил это.
Подобную проблему можно получить, слишком быстро преобразовав ее в экранные координаты, хотя API, который позволяет передавать ему координаты с плавающей запятой (что делает GDI+), имеет тенденцию быть гораздо более устойчивым к этому.
GDI Gotchas, которые сожгли меня несколько раз.
- Clone не клонирует () базовый клон данных (Rectangle, PixelFormat). Поэтому, если вы избавляетесь от clone(), исходный объект станет непригодным для использования. Используйте новый Bitmap(), если вы хотите два отдельных растровых изображения.
- Если вы загружаете изображение FromFile, этот файл блокируется до тех пор, пока изображение не будет удалено (даже не может быть прочитано).
- При использовании DrawImage не забудьте установить SmoothingMode, InterpolationMode и PixelOffsetMode, иначе вы будете удивлены низким качеством изображения.
Будьте осторожны при использовании регионов: http://steveperks.com/post/Fun-With-GDI2b-Bugs.aspx
Не совсем проблема GDI+, но помните об этом, чтобы сэкономить несколько часов на отладке:
Одна ошибка, которую я слишком часто делал, используя GDI+ в.NET, это вызов Matrix
методы на Transform
собственность Graphics
объект. Пример (в C++/CLI):
g->Transform->Translate(100.0f, 250.0f); // WRONG. Will not have any effect.
Добытчик Transform
свойство возвращает только копию матрицы. Поэтому любые методы, вызываемые в этой копии, не влияют на значение графического преобразования. Чтобы манипулировать графическим преобразованием, вызовите один из методов-оболочек (MultiplyTransform
, TranslateTransform
, ScaleTransform
и т. д.), как показано ниже.
g->TranslateTransform(100.0f, 250.0f);