Как использовать обертывание Graphics32 для преобразования полигональной области?

Graphics32 предоставляет пример переноса изображения (\Transformation\ImgWarping_Ex), в котором пользователь может использовать кисть для переноса части растрового изображения32. Однако этот образец действительно трудно понять, поскольку он смешивает множество сложных концепций.

Допустим, мне нужно преобразование обертывания, которое преобразует многоугольную область из одной формы в другую. Как я мог выполнить такую ​​задачу?


person jonjbar    schedule 02.08.2012    source источник
comment
Я действительно не знаю, с чего начать, и это то, что мне нужно: простая отправная точка.   -  person jonjbar    schedule 04.08.2012
comment
Вам нужен многогранный многоугольник или подойдет четырехгранный? Я могу помочь с этим, но я не использовал формы более высокого порядка.   -  person David    schedule 06.08.2012
comment
Четырехсторонний многоугольник был бы отличной отправной точкой. Я ценю любую помощь, которую вы можете дать, спасибо заранее!   -  person jonjbar    schedule 06.08.2012


Ответы (1)


Как и в комментариях, я не уверен насчет многогранника. Однако для преобразования одного четырехугольника в другой можно использовать проективное преобразование. Это отображает четверку из четырех точек в другую четверку из четырех точек. (Изначально я узнал об этом, когда -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
comment
Спасибо за ваш ответ, но мне жаль, что мне не нужно проективное преобразование, мне нужно преобразование обертывания, как показано в демонстрации Graphics32: Transformation\ImgWarping_Ex - person jonjbar; 08.08.2012