Как я могу отобразить квадратное растровое изображение на произвольный четырехсторонний многоугольник с помощью GDI?

Мне нужно нарисовать квадратное изображение, отображенное или преобразованное в неизвестный во время компиляции четырехсторонний многоугольник. Как я могу это сделать?

более длинное объяснение

конкретная проблема рендеринга тайлов с прямоугольной проекции. Предположим, у меня есть следующая плитка:

Square tile

и я знаю, что четыре угловые точки должны быть здесь:

Four distorted corners

учитывая это, я хотел бы получить следующее вывод:

Distorted, image-mapped polygon

квадратная плитка может быть:

  • повернуть; и/или
  • быть уже на одном конце, чем на другом.

Я думаю второй элемент означает, что для этого требуется неаффинное преобразование.

случайные дополнительные примечания

четырехгранный? правдоподобно, что, чтобы быть полностью правильным, плитка должна быть сопоставляется полигон с более чем четырьмя точками, но для наших целей и в масштабе он нарисован, квадрат - > другой четырехугольный многоугольник трансформации должно быть достаточно.

почему предпочтительно только GDI? все рендеринг до сих пор выполняется с помощью GDI, и я хочу сохранить код (a) быстро и (b) требуя как можно меньше дополнительных библиотеки, насколько это возможно. Я знаю о некоторую поддержку преобразования в GDI и экспериментировали с ними сегодня, но даже после экспериментируя с ними, я не уверен, что они достаточно гибкий для этого. Если они, я не сумел выясните это, и поэтому я был бы очень признателен за образец кода.

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

еще одна альтернатива-что угодно Дельфи- / C++Builder-specific; эта программа написана в основном на C++ с использованием VCL, и графика, о которой идет речь, в настоящее время окрашена в TCanvas со смесью методы TCanvas и необработанные вызовы WinAPI/GDI.

наложение изображений: последнее предостережение заключается в том, что один цвет в плитке может быть для цветового ключа прозрачность: то есть все белые (скажем) квадраты в вышеуказанной плитке должен быть прозрачным, когда нарисован поверх того, что находится под ним. В настоящее время плитки рисуются квадратными или выровненными по оси прямоугольными цели, используя TransparentBlt.

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

3 ответов


вы также можете посмотреть на Graphics32. Снимок экрана bewlow показывает, как демо transfrom в GR32 выглядит


посмотри 3D лаборатория векторной графики. (Специально "футбольное поле" в демо).


еще один классный ресурс AggPas С полным исходным включенных (скачать)

AggPas является открытым исходным кодом и бесплатно 2D векторной графики библиотеки. Это собственный порт объекта Pascal библиотеки антигравитационной геометрии-AGG, первоначально написанный Максимом Шеманаревым на C++. AggPas не зависит от графического API или технологии. В принципе, вы можете думать об AggPas как о механизме рендеринга, который создает пиксельные изображения в памяти из некоторых векторных данных.

вот как perspective демо выглядит так:

enter image description here

после преобразования:

enter image description here


общая техника описана в "искажении цифрового изображения" Джорджа Уолберга. Похоже на этот абстрактный содержит соответствующую математику, как это делает этой статье. Вам нужно создать перспективную матрицу, которая отображает из одного квадрата в другой. Приведенные выше ссылки показывают, как создать матрицу. После того, как у вас есть матрица, вы можете сканировать выходной буфер, выполнять преобразование (или, возможно, обратное-в зависимости от того, что они вам дают), и это даст вам очки в исходном изображении, которое можно скопировать.

возможно, проще использовать OpenGL для рисования текстурированного квадрата между 4 точками, но это не использует GDI, как вы хотели.