关于WriteableBitmap上的AddDirtyRect的WPF性能问题 [英] WPF performance problem regarding AddDirtyRect on WriteableBitmap

查看:402
本文介绍了关于WriteableBitmap上的AddDirtyRect的WPF性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

感谢您对线程中的线条图"提高线条绘制性能"的帮助。实际上,现在线条图几乎不消耗任何CPU时间。

Hello,

Thanks for your help regarding the line drawing in the thread "Improve line drawing performance". Actually, now the line drawing consumes virtually no CPU time at all.

然而,对于窗口大小为1200 * 900的应用程序仍需要大约35%的CPU在我的电脑上。我已经推出了一个小程序(见下文)来证明这个问题。在这个程序中,我完全删除了线条图,现在每秒只填充一个10 x 10像素的正方形,并将相同区域标记为脏。

如果1200 * 900像素的整个窗口被标记为脏而不是10 * 10平方,则CPU百分比几乎相同。如果省略对AddDirtyRect的调用,程序将降至0%。

一个有趣的效果是,如果窗口是,则程序占用大约0%的CPU而不是小型或中型(这适用于我的电脑屏幕的一半以上)。对于较大的窗口(例如1200 * 900),会发生奇怪的事情并且CPU使用率突然上升到大约。 35%。

我使用的是Dell Precision 370 Pentium 4,3GHz和NVIDIA Quadro NVS 280显卡IRQ 16 BIOS 4.34.20.79.08,但是在几种不同的计算机配置中都可以看到相同的效果。

有任何建议吗?

最好的问候,
G G

>使用System.Windows;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Timers;
使用System.Drawing;
using System.Drawing.Drawing2D;

namespace WpfTest
{
公共部分类Window1:Window
{
static Window1实例;
public const int DrawTimerPeriod = 20; // ms
public System.Drawing.Pen LinePen {get;组;公共System.Drawing.Brush BackGroundBrush {get;组; }
int controlHeight;
int controlWidth;
System.Drawing.Graphics bitmapGraphics;
WriteableBitmap drawingBitmap = null;
计时器drawTimer = new Timer(DrawTimerPeriod);
private delegate void DummyDelegate();

public Window1()
{
InitializeComponent();
instance =这个;
LinePen = new System.Drawing.Pen(System.Drawing.Color.Lime,1.0f);
BackGroundBrush = System.Drawing.Brushes.Black;

//设置计时器
drawTimer.Elapsed + = delegate
{
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
(DummyDelegate)委托{TimerEvent( );}};
};
drawTimer.Start();
}

private void UserControl_Loaded(object sender ,RoutedEventArgs e)
{
UserControl_SizeChanged(sender,null);
}

private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
System.Windows.Media.Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
double dpi_x = m.M11 * 96.0;
double dpi_y = m.M22 * 96.0;
controlWidth =(int)this.ActualWidth;
controlHeight =(int)this.ActualHeight;
drawingBitmap = new WriteableBitmap(controlWidth,controlHeight,dpi_x,dpi_y ,PixelFormats.Pbgra32,null);
bitmapI mage.Source = drawingBitmap;
System.Drawing.Bitmap b = new Bitmap(controlWidth,controlHeight,controlWidth * 4,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb,drawingBitmap.BackBuffer);
bitmapGraphics = System.Drawing.Graphics.FromImage(b);
bitmapGraphics.SmoothingMode = SmoothingMode.HighQuality;
bitmapGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
bitmapGraphics.CompositingMode = CompositingMode.SourceOver;
bitmapGraphics.CompositingQuality = CompositingQuality.HighQuality;

//填充背景
drawingBitmap.Lock();
bitmapGraphics .FillRectangle(BackGroundBrush,0,0,controlWidth,controlHeight);
bitmapGraphics.Flush(System.Drawing.Drawin) g2D.FlushIntention.Flush);
drawingBitmap.AddDirtyRect(new Int32Rect(0,0,controlWidth,controlHeight));
drawingBitmap.Unlock();
}

public void RenderStuff()
{
if if(drawingBitmap!= null)
{
drawingBitmap.Lock();
bitmapGraphics.FillRectangle(BackGroundBrush,10,10,20,20);
drawingBitmap.AddDirtyRect(new Int32Rect(10,10,20,20));
//drawingBitmap.AddDirtyRect(new Int32Rect( 0,0,1199,899));
drawingBitmap.Unlock();
}}}

public static void TimerEvent()
{
instance.RenderStuff();
}
}

< Window x:Class =" WpfTest.Window1"
xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml " title =" Window1"高度= QUOT; 900"宽度= QUOT; 1200"背景= QUOT;黑色" WindowStyle =" None"
Loaded =" UserControl_Loaded" SnapsToDevicePixels = QUOT;真" SizeChanged =" UserControl_SizeChanged">
< Grid>
< Image Name =" bitmapImage" SnapsToDevicePixels = QUOT;真" />
< / Grid>
< / Window>

        public static void TimerEvent()
        {
            instance.RenderStuff();
        }
    }
}


<Window x:Class="WpfTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="900" Width="1200" Background="Black" WindowStyle="None"
    Loaded="UserControl_Loaded" SnapsToDevicePixels="True" SizeChanged="UserControl_SizeChanged">
    <Grid>
        <Image Name="bitmapImage" SnapsToDevicePixels="True" />
    </Grid>
</Window>

推荐答案

一个快速尝试:使用 http://msdn.microsoft .com / zh-cn / library / system.windows.media.bitmapscalingmode.aspx 设置RenderOptions.BitmapScalingMode =" 线性 "你的Image元素甚至是NearestNeighbor。

- 亚当史密斯[MSFT]
One quick thing to try:  use http://msdn.microsoft.com/en-us/library/system.windows.media.bitmapscalingmode.aspx to set RenderOptions.BitmapScalingMode="Linear" or even NearestNeighbor on your Image element.

-Adam Smith [MSFT]


这篇关于关于WriteableBitmap上的AddDirtyRect的WPF性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆