如何在DrawingContext中渲染BitmapSource时关闭像素插值
实现方案
你可以通过修改RenderOptions.BitmapScalingMode附加属性实现无插值渲染,WPF的渲染上下文本身不直接携带插值配置,该属性作用于Visual或者Drawing对象的渲染管线,设置为BitmapScalingMode.NearestNeighbor即可实现最近邻采样,放大时保留清晰的像素边界。
方案1:全局设置控件的插值模式
如果你的自定义Image控件始终需要无插值渲染,直接在构造函数中设置附加属性即可,不需要修改OnRender逻辑:
public class CustomImage : Image { public CustomImage() { // 设置最近邻插值,关闭像素平滑 RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.NearestNeighbor); // 可选:设置边缘抗锯齿模式为别名,避免像素边缘出现半透明过渡 RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); } protected override void OnRender(DrawingContext dc) { base.OnRender(dc); // 你的叠加信息渲染逻辑 } }
方案2:仅在渲染BitmapSource时临时切换插值模式
如果控件还有其他需要插值的渲染逻辑,可以在OnRender中临时切换属性,渲染完成后恢复原值:
protected override void OnRender(DrawingContext dc) { // 保存原有插值模式 var originalScalingMode = RenderOptions.GetBitmapScalingMode(this); var originalEdgeMode = RenderOptions.GetEdgeMode(this); // 切换到无插值模式 RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.NearestNeighbor); RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); // 渲染原始BitmapSource base.OnRender(dc); // 恢复原有模式,再执行自定义叠加渲染(如果叠加内容需要插值的话) RenderOptions.SetBitmapScalingMode(this, originalScalingMode); RenderOptions.SetEdgeMode(this, originalEdgeMode); // 你的叠加信息渲染逻辑 }
方案3:基于DrawingGroup隔离渲染配置
如果你不想修改控件本身的附加属性,也可以用DrawingGroup包裹绘制内容,单独给绘制组设置插值模式:
protected override void OnRender(DrawingContext dc) { var drawingGroup = new DrawingGroup(); RenderOptions.SetBitmapScalingMode(drawingGroup, BitmapScalingMode.NearestNeighbor); RenderOptions.SetEdgeMode(drawingGroup, EdgeMode.Aliased); using (var groupContext = drawingGroup.Open()) { // 原始图像和叠加内容都在组上下文里渲染 base.OnRender(groupContext); // 你的叠加信息渲染逻辑 } dc.DrawDrawing(drawingGroup); }
内容的提问来源于stack exchange,提问作者HericDenis
相关产品推荐
相关产品推荐

