Может ли этот блиттер получиться быстрее? - PullRequest
4 голосов
/ 12 июня 2009

Когда я делаю редактор карт на основе плиток в C #, я склоняюсь к итерации по осям X, Y и вызываю Graphics.DrawImage (), чтобы переместить одну плитку на месте, из битовой карты набора плиток в битовую карту карты. Этот процесс занимает несколько секунд, поэтому я делаю это только один раз при загрузке новой карты или изменении набора тайлов. Любые правки с этого момента - относительно быстрые блики только отредактированного тайла.

Теперь, я сел сегодня утром и подумал о своих возможностях. Graphics.DrawImage () - единственный из трех (остальные - DrawImageUnscaled и DrawImageUnscaledAndCropped (?)), Который позволяет указать источник источника. DrawImageUnscaled () была намного, намного быстрее, но всегда вспыхивала в верхнем левом углу исходного растрового изображения.

В резком контрасте со скоростями QuickBasic PSET по сравнению с POKEing видеопамяти или VB6 PSet по сравнению с WinAPI SetPixel, простой цикл Get / SetPixel был таким же быстрым, как вызов DrawImageUnscaled , но обрезка, в противном случае только DrawImage сделал бы.

Пока это достаточно быстро, но мне было интересно, как что-то вроде прямой манипуляции с изображениями может ускорить это еще больше? Возможно, что-то с LockBits, функция, о которой я почти ничего не знаю?

Ответы [ 3 ]

1 голос
/ 12 июня 2009

простой цикл Get / SetPixel был таким же быстрым как вызов DrawImageUnscaled

Тогда вы определенно делаете что-то не так. Методы GetPixel и SetPixel имеют некоторые издержки, использование любого из методов DrawImage должно быть примерно в 100 раз быстрее (если, возможно, если ваши плитки очень маленькие, например, 2x2 пикселя).

Вопреки своему названию, метод DrawImageUnscaled не рисует без изменения размера. Вместо этого он использует настройки PPI изображений, чтобы масштабировать их до тех же измерений. Это означает, что если у вас есть растровое изображение с параметром 100 PPI и на нем нарисовано растровое изображение с параметром 50 PPI, его размер будет изменен до двойного размера.

Если вы рисуете изображения в неизменном размере, вы можете изменить настройки качества в объекте Graphics, чтобы настроить скорость. Например, вы можете установить для свойства InterpolationMode значение NearestNeighbor, чтобы оно не выполняло никакой интерполяции.

Альтернативой рисованию на растровом изображении может быть использование LockBits и UnlockBits для непосредственного доступа к пиксельным данным растрового изображения.

1 голос
/ 12 июня 2009

На этот вопрос есть отличный ответ .. Как управлять изображениями на уровне пикселей в C #

Если вы пойдете по маршруту LockBits, можете ли вы опубликовать продолжение с разницей в скорости.

1 голос
/ 12 июня 2009

Программный блиттинг кажется серьезным узким местом. Я бы серьёзно посоветовал изучить аппаратно-ускоренное рисование для такой задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...