如何使用 GDI 将方形位图渲染为任意四边形多边形?
Posted
技术标签:
【中文标题】如何使用 GDI 将方形位图渲染为任意四边形多边形?【英文标题】:How can I render a square bitmap to an arbitrary four-sided polygon using GDI? 【发布时间】:2012-03-25 09:37:48 【问题描述】:我需要绘制一个正方形图像,映射或转换为编译时未知的四边多边形。我该怎么做?
更长的解释
具体问题是使用非矩形地图投影渲染地图图块。假设我有以下磁贴:
我知道四个角点需要在这里:
鉴于此,我想得到以下输出:
方块可能是:
已旋转;和/或 一端比另一端窄。我认为第二项意味着这需要非仿射变换。
随机附注
四面? 完全正确,瓷砖应该是 映射到具有四个以上点的多边形,但出于我们的目的 并按照绘制的比例,一个正方形->其他四角多边形 改造应该就够了。
为什么最好只使用 GDI? 到目前为止,所有的渲染都是使用 GDI 完成的,我希望保持代码 (a) 快速和 (b) 只需要很少的额外代码 图书馆尽可能。我知道some support for transformations in GDI 并一直在尝试它们 今天,但即使在对它们进行试验之后,我也不确定它们是否 为此目的足够灵活。如果他们是,我还没有设法 弄清楚,所以我真的很感激一些示例代码。
GDI+ 也可以,因为我们在其他地方使用它,但我知道它可能很慢,而且速度是 这里很重要。
另一种选择是Delphi- / C++Builder-特定;这个程序主要是用 C++ 编写的 VCL,并且有问题的图形当前被绘制到 混合了TCanvas methods 和原始 WinAPI/GDI 调用的 TCanvas。
叠加图像: 最后一个警告是图块中的一种颜色可能是颜色键 透明度:即上面图块中的所有白色(比方说)方块 当绘制在下面的任何东西上时应该是透明的。 目前,瓷砖被绘制成正方形或轴对齐的矩形 目标使用TransparentBlt。
对于让这个问题变得更加复杂的所有额外警告,我深表歉意 而不是“我应该使用什么算法?”但我会很乐意接受答案 也只有算法信息。
【问题讨论】:
@NGLN:看起来很完美。我要么忘记了,要么从来不知道这个功能!我明天会尝试它(这里是深夜。)同时,您介意添加它作为答案吗? 糟糕,抱歉:PlgBlt 只能生成平行四边形。 如果速度很重要,您应该放弃 GDI 并开始使用 OpenGL。 Delphi 附带OpenGL
单元,因此您可以快速入门。 (GDI 可能很快足够,但既然你提到速度的重要性......)
@AndreasRejbrand,是的... OpenGL 会更快,当然为此。不过,我正在添加到现有视图中,并且不想重写整个内容,因此我更愿意与现有代码集成。但谢谢你的想法!我们实际上是considering using OpenGL elsewhere in the program 很快...
@DavidM,我真的不明白你还想要什么......你有完整的来源、项目名称和所需的输出。看看Graphics32
的优秀demo:这不是“具体库如何解决问题的具体例子”吗?
【参考方案1】:
您可能还想看看Graphics32。 下面的屏幕截图显示了 GR32 中的 transfrom 演示如何看起来像
【讨论】:
这在演示应用程序中运行良好,但在集成到更大的现有应用程序中时遇到了问题(我在 GR32 论坛上发帖,无需混乱,但主要问题是一些方法链接器找不到 TBitmap32 类,尽管它们在生成的 .hpp 文件中,我看不出有什么问题。)您是否将它与 C++ Builder 一起使用,您是否知道必须做些什么才能获得任何东西演示工作? @David,对不起,我是 Delphi 唯一的人。但是看看我在 GR32 论坛上的回复 @David :) 谢谢。在您的一个 cmets 中,您提到缺少文档。这不是真的,但有些隐蔽。看看here【参考方案2】:看看3D Lab Vector graphics。 (特别是演示中的“足球场”)。
另一个很酷的资源是AggPas,包含完整源代码 (download)
AggPas 是开源和免费的 2D 矢量图形库。它是 Anti-Grain Geometry 库 - AGG 的 Object Pascal 原生端口,最初由 Maxim Shemanarev 用 C++ 编写。 AggPas 不依赖于任何图形 API 或技术。基本上,您可以将 AggPas 视为一种渲染引擎,它从一些矢量数据在内存中生成像素图像。
perspective
演示如下所示:
改造后:
【讨论】:
看起来很酷。但它只是矢量吗?我正在处理位图 - 光栅图像。 @DavidM,我只看了一眼。我不确定。【参考方案3】:George Wolberg 的“数字图像变形”中描述了通用技术。看起来this abstract 包含相关数学,this paper 也是如此。您需要创建一个从一个四边形映射到另一个四边形的透视矩阵。上面的链接显示了如何创建矩阵。一旦你有了矩阵,你就可以扫描你的输出缓冲区,执行转换(或者可能是相反的 - 取决于他们给你的),这会给你原始图像中的点,你可以从中复制。
使用 OpenGL 在 4 个点之间绘制一个带纹理的四边形可能更容易,但这并不像您想要的那样使用 GDI。
【讨论】:
所以你实现了一个扫描线算法,很像渲染一个 3D 多边形,使用矩阵来查找原始图像中的像素值? 我将赏金授予上述 Graphics32 答案 - 这是一个有用且快速的库。但这也是一个很好的答案,我很高兴知道算法,如果可以的话,我会给你不止一个投票。以上是关于如何使用 GDI 将方形位图渲染为任意四边形多边形?的主要内容,如果未能解决你的问题,请参考以下文章