【问题标题】:Calculate the bounding box of a GDI+ drawing计算 GDI+ 绘图的边界框
【发布时间】:2010-12-19 06:27:37
【问题描述】:

我正在从 MetaFile (emf) 中绘制图像,然后在 UserControl 的 OnPaint 中对其应用一些旋转变换。应用这些转换后,我如何计算屏幕坐标中正常的未转换矩形边界框?我需要这个能够将旋转图像的大小调整为 UserControl 的大小。

protected override void OnPaint(PaintEventArgs e)
{
    // rotate around the center of this UserControl
    e.Graphics.TranslateTransform(this.Width / 2.0f, this.Height / 2.0f);
    e.Graphics.RotateTransform(this.Rotation);
    e.Graphics.TranslateTransform(this.Width / -2.0f, this.Height / -2.0f);

    // TODO: now scale so the image so it fits exactly into this UserControl

    // draw the image at the center of this UserControl
    float left = (this.Width - ResourceManager.MyDrawingMetaFile.Width) / 2.0f;
    float top = (this.Height - ResourceManager.MyDrawingMetaFile.Height) / 2.0f;
    e.Graphics.DrawImage(Resources.MyDrawingMetaFile, left, top);
}

这背后的整个想法是我想在 UserControl 中显示旋转的 .emf 文件,并让 emf 绘图始终填充 UserControl 中的可用空间。也许有更好的方法?

我所追求的填充模式/拉伸模式是 Uniform 和 UniformToFill(就像在 WPF 的 Viewbox 中一样)。 emf 不应该被扭曲,在 Uniform 模式下,emf 至少在一个维度上完全填充用户控件,没有任何东西被裁剪。在 UniformToFill 中,emf 在两个维度上填充 UserControl,如果纵横比不匹配,则在一个维度上裁剪 emf。

【问题讨论】:

  • 您希望它如何“填充”? emf 应该完全覆盖用户控件(应该裁剪 emf 的某些部分)还是应该调整大小以使所有 emf 都可见 - 让用户控件的部分被覆盖? emf 是否应该保持原来的纵横比?
  • 我追求的 fillmode/stretchmode 是 Uniform 和 UniformToFill(就像在 WPF 的 Viewbox 中一样)。 emf 不应该被扭曲,在 Uniform 模式下,emf 至少在一个维度上完全填充用户控件,没有任何东西被裁剪。在 UniformToFill 中,emf 在两个维度上填充 UserControl,如果纵横比不匹配,则在一个维度上裁剪 emf。

标签: c# gdi+ resize bounding-box


【解决方案1】:

如果我理解正确 - 您需要弄清楚旋转如何影响图像的边界框,以便您可以相应地对其进行缩放。

那么你可以这样做:

  1. 将边界框的四个坐标填充到 Point[] 中。
  2. 使用旋转 (.RotateAt) 设置矩阵
  3. 让矩阵变换四个点。
  4. 对四个变换后的X坐标进行排序,比较新边界框的宽度(排序后的pts[3].X - pts[0].X)。
  5. 现在您知道如何缩放宽度以获得完美契合。
  6. 对高度也重复第 4 步。

【讨论】:

  • 我的图纸不一定是矩形的。例如,如果绘图是圆形,则旋转本身不会影响比例因子。
  • 那么你需要对图像中的每个进行上述操作。当然,一个圆必须是近似的,并且被认为是由许多线段组成的。
  • 我想知道,WPF(可能在 DWM 层的某处)是如何做到这一点的。
【解决方案2】:

使用 GDI 的方式是:

BeginPath()
// Draw stuff
EndPath()
PathToRegion()
GetRgnBox()

GDI+ 有等价物 - GraphicsPath 和 Region 类可以完成上述操作

【讨论】:

  • 我的绘图来自图元文件,所以我认为 GraphicsPath 不适用。
  • 元文件只是 GDI 调用的序列化,因此它应该与 GraphicsPath 一起使用。无论如何 MetaFile 类有一个 GetMetafileHeader 方法,您可以获取图元文件边界框并使用三角函数来获取旋转后的大小。
  • 那么 GraphicsPath 没有 AddMetaFile 或 AddDrawing 或类似方法。
  • 还因为绘图不是矩形(它可以是圆形或复杂路径)以获得正确的边界框,我需要在应用转换后获取边界框。使用三角函数重新计算旋转边界框的大小是不够的。
猜你喜欢
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 2019-09-05
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多