如何使用Graphics32包装转换来转换多边形区域?

时间:2012-08-02 16:12:16

标签: delphi graphics32

Graphics32提供了一个Image Wrapping示例(\ Transformation \ ImgWarping_Ex),用户可以使用画笔来包装bitmap32的一部分。然而,这个样本很难理解,因为它混合了许多复杂的概念。

假设我需要一个包裹变换,它可以将多边形区域从一种形状转换为另一种形状。我怎么能完成这样的任务呢?

1 个答案:

答案 0 :(得分:1)

在评论中,我不确定多边形多边形。但是,要将一个四边形转换为另一个四边形,可以使用投影变换。这将由四个点组成的四边形映射到四个点的另一个四边形。 (我最初在I asked this SO question时发现了这一点。)

您:

  • 使用Transform方法
  • 传入目标和源位图
  • 传入投影变换对象,使用目标点
  • 初始化
  • 传入光栅化器,该光栅化器控制输出像素从一个或多个输入像素的制作方式

光栅化器至少是可选的,但是通过指定除默认值之外的高质量(较慢)光栅化器链,您将获得更高质量的输出。还有其他可选参数。

它们的关键是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;

光栅化器是图像质量的一个重要参数 - 上面的代码会给你一些有效但不漂亮的东西,因为它会使用最近邻点采样。您可以构建一系列对象以获得更好的结果,例如将TSuperSamplerTRegularRasterizer一起使用。你可以read about samplers and rasterizers and how to combine them here.

Transform方法还有大约五种不同的重载,值得在GR32_Transforms.pas文件的界面中读取它们,以便了解可以使用的版本。