Может ли этот плиточный блитер стать быстрее?


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

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

В резком контрасте со скоростями из quickbasic PSET против POKEing видео памяти, или в VB6 по PSet против по WinAPI это методом setpixel, простой get/метода setpixel цикл был так же быстро, как DrawImageUnscaled звонок, а не обрезки, что только метода drawImage иначе бы обошлось.

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

3 4

3 ответа:

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

Если вы идете по маршруту Локбитов, не могли бы вы опубликовать продолжение с различиями в скорости.

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

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

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

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

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

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