如何使用WPF控制像素获得WritableBitmap像素1:1? [英] Howto get WritableBitmap pixels 1:1 with WPF Control pixels?

查看:262
本文介绍了如何使用WPF控制像素获得WritableBitmap像素1:1?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使调整控件的大小,如何有效地获取WritableBitmap的像素以匹配屏幕上的像素1:1?

How can I efficiently get the pixels of a WritableBitmap to match on-screen pixels 1:1, even as a control is resized?

或者,如何像Windows.Forms一样快速地在WPF中使用文本快速进行2d矢量绘制?

Or alternatively, how can I do fast 2d vector drawing with text in WPF, as fast as Windows.Forms?

背景:

我有一个简单的Windows.Forms应用程序,我正在尝试将其转换为WPF.它具有用户绘制的控件,该控件会随音频电平图不断更新.在Windows.Forms中,控件会定期调用Invalidate,并具有一个绘制它的OnPaint处理程序.

I have a simple Windows.Forms app I'm trying to convert to WPF. It has a user-drawn control which is continuously updated with an Audio Level Graph. In Windows.Forms, the control periodically calls Invalidate, and has an OnPaint handler which draws it.

我在WPF中的第一次尝试是将UIElement用于用户绘制的控件.但是,我唯一想重绘的方法是InvalidateVisual(),它会导致完全重新布局并且运行缓慢.同样,使用DrawingContext绘制文本的速度也非常慢.

My first attempt in WPF was using a UIElement for the user-drawn control. However, the only way I could figure out to repaint it was InvalidateVisual() which causes a full relayout and was slow. Also drawing text with DrawingContext is incredibly slow.

我当前的代码是将Image用于用户绘制的控件,并使用System.Drawing.Graphics绘制到该图像的WriteableBitmap源上.这非常快并且效果很好.

My current code is using Image for my user-drawn control, with System.Drawing.Graphics to paint onto a WriteableBitmap source for the image. This is extremely fast and works well.

但是,我无法弄清楚如何有效地将Imageable控件的WriteableBitmap大小调整为1:1且带有屏幕像素.我试图使用LayoutUpdated来制作一个具有新大小的新WritableBitmap,并将其设置为Image.Source,但这实在令人难以置信 慢.

However, I can't figure out how to efficiently get the WriteableBitmap to be sized 1:1 with screen-pixels for the Image control. I tried to use LayoutUpdated to make a new WritableBitmap with the new size, and set it as the Image.Source, but this is incredibly slow.

您可以在此处查看我当前的代码:

You can see my current code here:

https://github.com/jeske/SoundLevelMonitor/blob/master/SoundLevelMonitorWPF/SoundLevelMonitor/AudioLevelsUIElement.cs#L46

https://github.com/jeske/SoundLevelMonitor/blob/master/SoundLevelMonitorWPF/SoundLevelMonitor/AudioLevelsUIElement.cs#L46

推荐答案

我解决了我的问题.

I solved my problem.

捕获调整大小事件的正确方法是侦听Image.SizeChanged事件,该事件仅在大小改变时才触发.在该事件处理程序中,我制作了一个新的WriteableBitmap,其大小为RenderSize,将其设置为Image.Source,并且一切都很好. 世界.我还必须将Image控件设置为Stretch ="Fill".以防止其保持底层位图的长宽比.

The correct way to catch the resize events is to listen to the Image.SizeChanged event, which only fires when the size changes. Inside that event handler I make a new WriteableBitmap of size RenderSize, set that to the Image.Source, and all is good in the world. I also had to set the Image control to Stretch="Fill" to prevent it from maintaining the underlying bitmap's aspect ratio.

Image.LayoutUpdated,这会导致性能下降. 

Image.LayoutUpdated is actually fired every time the content changes, and this was causing the bad performance. 


这篇关于如何使用WPF控制像素获得WritableBitmap像素1:1?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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