Как и в комментариях, я не уверен насчет многогранника. Однако для преобразования одного четырехугольника в другой можно использовать проективное преобразование. Это отображает четверку из четырех точек в другую четверку из четырех точек. (Изначально я узнал об этом, когда -using-gdi">Я задал этот ТАК вопрос.)
Ты:
- Используйте метод преобразования
- Передать целевое и исходное растровое изображение
- Передайте объект проективного преобразования, инициализированный точками назначения.
- Передайте растеризатор, который контролирует, как выходной пиксель создается из одного или нескольких входных пикселей.
По крайней мере, растеризатор является необязательным, но вы получите более качественный результат, указав более качественную (более медленную) цепочку растеризатора, отличную от используемой по умолчанию. Есть и другие необязательные параметры.
Ключом является объект TProjectiveTransformation
. К сожалению, в документации Graphics32, похоже, отсутствует запись для Transform method
, поэтому я не могу ссылаться на нее. Однако вот непроверенный пример кода, основанный на моем коде. Он преобразует прямоугольное исходное изображение в выпуклый четырехугольник на целевом изображении:
var
poProjTransformation : TProjectiveTransformation;
poRasterizer : TRegularRasterizer;
oTargetRect: TRect;
begin
// Snip some stuff, e.g. that
// poSourceBMP and poTargetBMP are TBitmap32-s.
poProjTransformation := TProjectiveTransformation.Create();
poRasterizer := TRegularRasterizer.Create();
// Set up the projective transformation with:
// the source rectangle
poProjTransformation.SrcRect = FloatRect(TRect(...));
// and the destination quad
// Point 0 is the top-left point of the destination
poProjTransformation.X0 = oTopLeftPoint.X();
poProjTransformation.Y0 = oTopLeftPoint.Y();
// Continue this for the other three points that make up the quad
// 1 is top-right
// 2 is bottom-right
// 3 is bottom-left
// Or rather, the points that correspond to the (e.g.) top-left input point; in the
// output the point might not have the same relative position!
// Note that for a TProjectiveTransformation at least, the output quad must be convex
// And transform!
oTargetRect := TTRect(0, 0, poTarget.Width, poTarget.Height)
Transform(poTargetBMP, poSourceBMP, poProjTransformation, poRasterizer, oTargetRect);
// Don't forget to free the transformation and rasterizer (keep them around though if
// you're going to be doing this lots of times, e.g. on many images at once)
poProjTransformation.Free;
poRasterizer.Free;
Растеризатор является важным параметром качества изображения — приведенный выше код даст вам что-то, что работает, но некрасиво, потому что он будет использовать выборку ближайшего соседа. Вы можете построить цепочку объектов, чтобы получить лучшие результаты, например, используя TSuperSampler
с TRegularRasterizer
. Вы можете ознакомиться с семплерами и растеризаторами и их комбинацией здесь.
Также существует около пяти различных перегрузок для метода Transform
, и их стоит бегло прочитать в интерфейсе файла GR32_Transforms.pas
, чтобы знать, какие версии можно использовать.
person
David
schedule
07.08.2012