问题标签 [drawingcontext]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1802 浏览

c# - WPF DrawingContext 在我的对象后面绘制

我有一个带有一些图像的画布,并且我也在使用 DrawGeometry 来绘制一个在时间流逝时正在填充的圆圈。

这就是我在 DrawingContext 中绘制圆圈的方式:

并调用 InvalidateVisual(); 调用它。

但是这样做我的圈子在我的图像后面,我看不到它,我怎么能在它们前面画呢?

我对 WPF 完全陌生,这让我很难过....

这是请求的其他方法代码:

0 投票
1 回答
4486 浏览

c# - 提高 DrawingContext 性能渲染几何(多边形和折线)

这是我的第一个问题,但我是一个很长时间的潜伏者。我将把它分成两部分,一部分解释我在做什么以及为什么我认为这是要走的路,第二部分是我自己无法解决的实际问题。

我在做什么? 我目前正在开发一个用于渲染要实时显示的二维特征的框架。您可以在浏览器中考虑像 Google Maps 这样的应用程序,但该框架旨在呈现各种地理数据(不仅仅是轴对齐的栅格数据,如那些 Google Tiles)。

该框架将集成到我们(公司的)最新产品中,该产品是用于台式机和笔记本电脑的 WPF 应用程序。

因此,我选择 WPF仅用于实际渲染几何图形;可见性和遮挡剔除以及输入处理(鼠标拾取)、移动相机等都是我自己完成的。

作为一个实时应用程序,它至少需要达到 30 FPS。该框架在渲染图像时表现良好:我可以毫无问题地每帧绘制数千张位图,但事实证明多面体数据是一个主要问题。

我正在使用 WPF 渲染大量折线和多边形数据的实际问题,特别是使用 DrawingContext 和 StreamGeometry。到目前为止,我的理解是,如果我需要性能,这是要走的路。但是,我无法达到预期的结果。

这就是我用实际数据填充 StreamGeometry 的方式:

这就是我绘制几何图形的方式:

作为测试,我将 OpenStreetMap 中的 ESRI 形状加载到我的应用程序中以测试其性能,但我一点也不满意:我的测试数据包含约 3500 条线段,总共约 2 万条线。

将每个段映射到它自己的 StreamGeometry 表现非常糟糕,但我已经预料到了:渲染大约需要 14 秒。

然后我尝试使用多个数字将更多段打包到同一个 StreamGeometry 中:80 StreamGeometry,渲染大约需要 50 毫秒。

但是,我无法得到比这更好的结果。将行数增加到 100k 左右会使我的应用程序几乎无法使用:渲染时间超过 100 毫秒。 除了在渲染矢量数据时冻结几何体和笔,我还能做什么?

我现在宁愿自己使用 DirectX,也不愿依赖 WPF 来做这件事,因为某些事情似乎出了大问题。

编辑

为了进一步澄清我在做什么:该应用程序实时可视化地理数据,非常类似于浏览器中的谷歌地图等应用程序:但是它应该可视化更多的数据。您可能知道,Google Maps 允许缩放和平移,这需要 > 25 FPS 才能显示为流畅的动画;少了什么都感觉不流畅。

* 抱歉,我不应该在实际产品发布之前上传此视频。然而,您可能会想到类似 Google Maps 的东西,但是有大量的矢量数据(多边形和折线)。*

有两种解决方案,其中一种经常被提及:

在位图中缓存重绘图

实现似乎有点简单,但是我发现这种方法存在一些问题:为了正确实现平移,我需要避免在每帧绘制繁重的东西,因此我可以选择在平移时不更新缓存的位图相机,或者创建一个覆盖比视口更大的区域的位图,所以我只需要每隔一段时间更新一次缓存的位图。

第二个“问题”与缩放有关。然而,它更像是一个视觉伪影而不是一个真正的问题:由于缓存的位图无法以 30 FPS 正确更新,因此在缩放时我也需要避免这种情况。我可以在缩放时很好地缩放位图,仅在缩放结束时创建一个新的位图,但是折线的宽度不会具有恒定的厚度,尽管它们应该。

MapInfo 似乎确实使用了这种方法,但是我不能说我太喜欢它了。不过,它似乎是最容易实现的。

将几何图形拆分为不同的绘图视觉效果

这种方法似乎以不同的方式处理问题。我不确定这种方法是否有效:这取决于我是否正确理解 WPF 在该领域应该如何工作。与其对所有需要绘制的东西使用一个 DrawingVisual,我应该使用几个,这样就不是每个都需要 RenderOpened()。我可以简单地更改参数,例如上面示例中的矩阵,以反映相机平移和移动。但是我也看到了这种方法的一些问题:平移相机将不可避免地将新的几何图形带入视口,因此我需要执行与第一种方法类似的操作,实际渲染当前不可见但可能变得可见的东西由于相机移位;

与这两种方法相关的 问题 这两种方法都无法解决的一个大问题是,即使整体帧速率稳定,在更新缓存位图时偶尔也会出现中断(好吧,如果缓存位图仅当相机不再平移时更新)或调用 RenderOpen 绘制可见的几何块,似乎是不可避免的。

到目前为止我的想法

由于这是我见过的解决这个问题的仅有的两个解决方案(我已经做了一年多的谷歌搜索),我想到目前为止唯一的解决方案是接受即使是最强大的 GPU 上的帧率提升(它应该能够每秒光栅化数亿个图元),视口的延迟更新(在位图仅在视口不再移动时更新的情况下)或根本不使用 WPF 并求助于 DirectX直接地。

我很高兴能得到帮助,但我不能说我对 WPF 的渲染性能印象深刻。

0 投票
4 回答
4319 浏览

c# - 渲染到自定义的 DrawingContext

我想劫持通常的 WPF 渲染来将控件拆分为基元,进行布局管理,为我应用绑定等。

据我了解,WPF 中的整个渲染归结为在布局管理器计算的位置处使用依赖属性系统定义的值渲染图元(文本、图像、线条、曲线)。如果我可以提供自己的原始渲染逻辑,我将能够渲染例如自定义文档类型,传输原始渲染以通过网络进行真实渲染等。

我的计划如下:

  1. 实现一个自定义DrawingContext. TheDrawingContext是一个抽象类,它定义了一堆方法,如,DrawEllipse等。我需要为这个功能提供我自己的实现。DrawTextDrawImage
  2. 创建一个 WPFUserControl并强制它渲染到给定的DrawingContext.

但是我遇到了以下问题:

  1. DrawingContext包含抽象的内部方法void PushGuidelineY1(double coordinate)void PushGuidelineY2(double leadingCoordinate, double offsetToDrivenCoordinate),我不能轻易覆盖。(也许有一些技巧可以克服这个问题?)
  2. 似乎没有方法可以DrawingContext? 为什么?

我可以做类似的事情

- 但我想知道是否有直接的方法来渲染UIElement. (当然,这个问题是一个小问题,但没有看到它的基础设施让我怀疑这是否是正确的方法。)

那么,DrawingContext不是为了继承吗?提供定制的整个想法是DrawingContext朝着正确方向迈出的一步,还是我需要重新考虑策略?是在 WPF 支持的自定义上下文上绘图,还是我需要寻找不同的拦截点?

0 投票
1 回答
1017 浏览

wpf - wpf中drawcontext绘制的几何图形上的阴影

我正在使用以下代码使用绘图上下文在文本框上渲染一个矩形。

我想在这个矩形上渲染一个阴影,我在 WPF 中以编程方式绘制。我该怎么做 ?

0 投票
1 回答
2457 浏览

c# - 更改 FormattedText 的文本

我正在使用以下方法将文本写入我的 MainWindow。我的问题是,有没有办法在创建后更改 FormattetText 或绘图视觉的文本?或者如果我想在运行时更新它,我应该使用另一种方法来编写我的文本吗?

0 投票
1 回答
4223 浏览

c# - WriteableBitmap(Ex) 与 DrawingContext 的性能

我正在 WPF 中构建一个自定义 UI 框架,我基本上尽可能多地抛弃内置布局系统和控件。到目前为止,我一直在UIElement直接分支,但由于我已经在进行测量、安排和渲染自己,我想我可以通过“更接近金属”(尤其是当它来布局/渲染)。留在托管代码中并且不害怕自己做肮脏的工作时有多接近?

我现在正在玩弄一个原型概念,我只有一个从 UIElement 继承的元素:一个Root对象,类似于一个剥离的对象Canvas,它“托管”我的布局引擎的其余部分并将相关的IInputElement好处引入其中。从那时起,所有元素都将是完全自定义的对象,不继承自 WPF 中的任何内容,而是直接呈现到DrawingContextRoot 中(在其OnRender方法中)。

现在我想知道拥有一个根元素并手动绘制它的相对性能,例如为了方便WriteableBitmap使用WriteableBitmapEx 。没有抗锯齿不是问题,自定义命中测试系统也不是问题。

我的想法主要是 WriteableBitmap(Ex) 没有任何 GPU 加速增益的特权,因此当需要重新绘制/转换大面积区域时会[非常]慢。

不过,我确实对“引擎中的基于像素的渲染引擎”有其他需求,因此我仍然对此感兴趣。

有什么见解吗?

编辑:在这种情况下,SharpDX 呢?也许一旦我这样做了,我还不如去使用像 SharpDX 这样的 DirectX 包装器的 WinForms 解决方案(..or.. 我想我真正应该做的是注册整个 C++ enchilada,但不幸的是我没有有时间在事情中开始学习)..

0 投票
2 回答
1911 浏览

c# - WPF DrawGeometry 不绘制描边

我希望以前没有问过这个问题,我到处搜索。

我的问题是我在我的 wpf 用户控件上用点绘制了一组坐标,我设法用背景颜色而不是笔划填充我的多边形。斯托克因为某种原因不画画?

这是我在 OnRender 事件中使用 DrawingContext 的代码

代码详细

StreamGeometry streamGeometry = new StreamGeometry();

}

我很乐意提供更多细节。

太感谢了。

0 投票
1 回答
396 浏览

wpf - WPF FormattedText 在高分辨率图像中随机消失

我需要创建 600 个 DPI “三折”图像,其尺寸为 25.5"x11"(是 Letter 页面大小的三倍)。为此,我通过 DrawingVisual、DrawingContext 和 RenderTargetBitmap 类使用 WPF Imaging。

当我以较低的分辨率(例如 400 DPI 或更低)生成图像时,所有文本都按预期显示在正确的位置。但是,一旦我将图像分辨率提高到 500 DPI 级别或更高,位于图像最右侧的某些文本将简单地消失,而其他相对定位的文本/形状则可以完美打印。最疯狂的部分是,当我尝试不同的 DPI 时,会出现/消失不同的文本。在一个测试案例中,600 DPI 缺少一组绘制的 FormattedText,650 DPI 缺少另一组绘制的 FormattedText,700 DPI 打印一切正常!

我用下面的代码片段重新创建了这个问题。按原样运行(600 DPI),你得到的只是一张非常大的白色图像。将 Dpi 常数更改为 400 或更低,它可以很好地打印文本。

请注意,我已尝试转动 DrawingVisual 类中的许多旋钮(例如 VisualBitmapScalingMode、VisualTextRenderingMode、VisualEdgeMode 等),但无济于事。我对这些设置的大部分研究发现它们是纠正“模糊”文本而不是消失文本的有用设置。我对 DrawingVisual 或 DrawingContext 的任何指南/捕捉设置也没有运气。

请注意,我已经在 Win7 和 Win2008R2 上重新创建了此问题,并且我的应用程序正在运行 .NET 4.5。

有任何想法吗?

0 投票
1 回答
263 浏览

c# - 如何将纹理图像 .jpg 用作 Windows.Media.pen C#

我有一个 .jpg 格式的纹理图像,我想将此图像用作 Windows.Media.pen

我使用 Windows.Media.pen 在从 microsoft kinect 获得的 DrawingContext 中绘制骨架数据。

如何将纹理图像 .jpg 用作 Windows.Media.pen?


解决了这个问题。

0 投票
2 回答
2690 浏览

wpf - 试图在 WPF 窗口中绘制一个椭圆,但它不可见

我正在尝试创建自己的图形用户控件,我已经在处理 win 表单,并且正在尝试将其移至 WPF 世界。

我从学习如何绘制开始,所以我首先尝试绘制一个填充整个窗口的黑色椭圆,只是为了了解坐标在 WPF 中的工作原理。

所以这里是代码,当我运行应用程序时,什么都没有显示,知道我错过了什么吗?