绘制大量半透明矩形,wpf和GDI哪个效率高?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了绘制大量半透明矩形,wpf和GDI哪个效率高?相关的知识,希望对你有一定的参考价值。
可能绘制大约3万个矩形,另外还有一些圆形和不规则图形(自定义顶点)。
用GDI+的 FillRectangle 或者 WPF的Shapes.Rectangle 哪个效率高?
不需要移动,但经常要更换新的一批图形。
可能绘制大约3万个矩形,另外还有一些圆形和不规则图形(如三角六角之类的)。
用GDI+的 FillRectangle 或者 WPF的Shapes.Rectangle 哪个效率高?
不需要移动,但经常要更换新的一批图形,所以效率很重要。
计划的是:
如果用GDI,大致上重绘BITMAP,
如果用WPF,则可能需要清空List<Shapes> , 然后再重绘。
不知道还有其他更好的解决方案不?
建议你用WPF的DrawingContext,你只需要记录矩形的属性,需要画出来的时候用DrawingContext画一遍就好了追问
初步尝试,绘制20000个矩形
1、用GDI,需要140ms,另外。把Bitmap转为BitmapImage需要额外的100ms
2、用Rectangle,约需要500ms,
3、用visual +DrawingContext,需要14000ms,而且刷新明显迟钝。不知道是不是算法有问题??
你不会每次需要的时候都重新用DrawingContext绘制出来吧……需要的时候再画,比如矩形变化的时候。
不清楚你的变化频率如何,如果像游戏那样的变化频率,你每次frame刷新的时候都用DrawingContext,那么底层的缓存就根本没用了。
我需要是从数据库查询出20000个数据,包括坐标和颜色,生成一个图片。当然这20000个点可能随查询条件的改变而改变。
我优化了代码:
绘图部分需要95ms,后面转化部分需要350ms,共计450ms左右。还是比GDI慢一点。
DrawingContext不是为线性图形绘制做优化的。
你这样只不过是输出一个Bitmap而已,建议你使用流图形输出,参考这里:http://msdn.microsoft.com/en-us/library/system.windows.media.streamgeometry.aspx
谢谢老兄的内心帮助!
按您的建议对流进行测试。
执行时间是45ms左右。的确快很多。但是有两个问题:
一:每个方格的颜色是不一样的。按这个方法,似乎先按颜色分别绘制,这样要增加额外的开销。
二:致命问题,由于geometry里面内容太多,导致绘制好之后,调整窗口大小等可能需要重绘的操作都出现迟钝,影响用户体验的迟钝。
如果要改善这点,要把myPath转为image之类的,不知道如何高效转?
你说你经常要更新新的一批图形,那么这种效率是最高的了,因为缓存对于这种大量更新的图形没有一点儿用处。
能想到的优化方式就是绘制前进行算法方面的优化,就跟游戏一样,计算场景中那些在前景哪些在背景,被遮挡的在背景的元素就不进行绘制了,筛选出需要绘制的图形这样速度就会快很多。
WPF将矩形宽度和高度绑定到主对话框
【中文标题】WPF将矩形宽度和高度绑定到主对话框【英文标题】:WPF Binding Rect Width and Height to the main Dialog 【发布时间】:2019-12-16 17:55:09 【问题描述】:如何正确地将矩形的宽度和高度绑定到对话框本身的边界?这样绘制的矩形总是覆盖整个窗口的客户空间。
现在每当我使用我的绑定代码(目前已被注释掉)时,它似乎都无法正确调整矩形的大小。它应该显示一个带有透明窗口切口的大对话框。
XML
<Window x:Class="WpfSnipping.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfSnipping"
mc:Ignorable="d"
Title="MainWindow"
Height="500"
Width="500"
AllowsTransparency="True"
WindowStyle="None"
Topmost="True"
Background="Transparent">
<Window.Resources>
<local:RectConverter x:Key="RectConverter"></local:RectConverter>
</Window.Resources>
<Grid x:Name="MainGrid">
<Canvas >
<Path Stroke="Black" Fill="White" Opacity=".3">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,300,300">
<!--<RectangleGeometry.Rect>
<MultiBinding Converter="StaticResource RectConverter">
<Binding ElementName="MainGrid" Path="Width"/>
<Binding ElementName="MainGrid" Path="Height"/>
</MultiBinding>
</RectangleGeometry.Rect>-->
</RectangleGeometry>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="50,50,100,100">
</RectangleGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Canvas>
</Grid>
</Window>
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfSnipping
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
public class RectConverter : IMultiValueConverter
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
return new System.Windows.Rect(0, 0, (double)values[0], (double)values[1]);
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
throw new NotImplementedException();
#endregion
【问题讨论】:
如果您删除 `Rect="0,0,300,300"',它应该会占用您想要的所有空间。不确定你想要什么。 【参考方案1】:绑定到ActualWidth
和ActualHeight
,因为只要MainGrid
的大小发生变化,这些依赖属性就会更新:
<RectangleGeometry.Rect>
<MultiBinding Converter="StaticResource RectConverter">
<Binding ElementName="MainGrid" Path="ActualWidth"/>
<Binding ElementName="MainGrid" Path="ActualHeight"/>
</MultiBinding>
</RectangleGeometry.Rect>
【讨论】:
以上是关于绘制大量半透明矩形,wpf和GDI哪个效率高?的主要内容,如果未能解决你的问题,请参考以下文章
htmlcss和js原生写一个模态弹出框,顺便解决父元素半透明子元素不透明效果
delphi 怎样绘制半透明窗体,只让窗体背景半透明,而窗体里面的控件 不透明