SharpDX Direct2D绘制负坐标位图时RawRectangleF截断问题求解
问题分析与解决办法
你的问题核心在于创建BitmapRenderTarget时只覆盖了正坐标区域,负坐标的DXF对象根本没被渲染到位图里,所以后续DrawBitmap时负区域自然没有内容。
具体问题点
在LoadBitmap方法中,你创建BitmapRenderTarget用的是new Size2F((float)Extents.Right, (float)Extents.Bottom),这相当于只创建了从(0,0)到(Right,Bottom)的画布,所有负坐标的对象都在这个画布之外,根本没被绘制。
解决步骤
- 计算完整的画布范围:要包含所有正负坐标的对象,画布宽度应该是
Extents.Right - Extents.Left,高度是Extents.Bottom - Extents.Top(因为Extents.Left可能为负,这样宽度才是实际总跨度)。 - 渲染DXF对象时做坐标平移:把所有对象的坐标加上偏移量
(-Extents.Left, -Extents.Top),这样原来的负坐标会被移到位图的正区域内,确保所有内容都能被绘制到位图里。 - 渲染位图时匹配视图坐标:根据当前的视图平移需求,计算位图对应区域的位置,绘制到目标RenderTarget上。
修改后的代码示例
1. 调整LoadBitmap方法
private void LoadBitmap(RenderTarget target) { if (LayerManager is null) { return; } if (bitmapRenderTarget is not null) { bitmapRenderTarget.Dispose(); bitmapRenderTarget = null; } // 计算完整的画布尺寸:包含正负坐标的总跨度 float canvasWidth = (float)(Extents.Right - Extents.Left); float canvasHeight = (float)(Extents.Bottom - Extents.Top); // 创建覆盖所有区域的BitmapRenderTarget bitmapRenderTarget = new BitmapRenderTarget(target, CompatibleRenderTargetOptions.None, new Size2F(canvasWidth, canvasHeight)); bitmapRenderTarget.BeginDraw(); bitmapRenderTarget.Clear(new RawColor4(1.0f, 1.0f, 0f, 1.0f)); // 计算坐标偏移量,把所有对象移到位图的正区域内 float offsetX = (float)-Extents.Left; float offsetY = (float)-Extents.Top; foreach (var layer in LayerManager.Layers.Values) { if (layer.IsVisible) { foreach (var o in layer.DrawingObjects) { if (o is DrawingLine drawingLine) { drawingLine.UpdateBrush(drawingLine.DxfLine, bitmapRenderTarget); // 这里需要修改DrawLine逻辑,支持传入偏移量处理坐标平移 DxfHelpers.DrawLineWithOffset(drawingLine, bitmapRenderTarget.Factory, bitmapRenderTarget, currentThickness, offsetX, offsetY); } } } } bitmapRenderTarget.EndDraw(); bitmapRenderTargetNeedsUpdate = false; bitmapLoaded = true; }
2. 调整RenderBitmap方法
private void RenderBitmap(RenderTarget target) { if (bitmapRenderTarget is not null) { if (bitmapRenderTargetNeedsUpdate) { LoadBitmap(target); } // 假设当前视图平移量为viewOffsetX、viewOffsetY float viewOffsetX = -200; float viewOffsetY = -200; // 位图源矩形:对应视图区域在已平移位图中的位置 RawRectangleF sourceRect = new( (float)(-viewOffsetX - Extents.Left), (float)(-viewOffsetY - Extents.Top), (float)(500 - Extents.Left), (float)(1000 - Extents.Top) ); // 目标矩形:RenderTarget上的显示位置 RawRectangleF destRect = new(-200, -200, 500, 1000); target.DrawBitmap(bitmapRenderTarget.Bitmap, destRect, 1.0f, BitmapInterpolationMode.Linear, sourceRect); } }
额外优化建议
- 不需要每次修改视图都重新生成位图:可以通过设置
RenderTarget.Transform实现平移缩放,仅在DXF内容变化时更新位图,提升大文件处理性能。 - 若缩放频繁,可根据当前缩放级别生成对应分辨率的位图,或直接用RenderTarget的Transform结合局部重绘,避免频繁生成大位图。
内容的提问来源于stack exchange,提问作者user25472896
相关产品推荐
相关产品推荐

