在 Wpf C# 中画一条直线
Posted
技术标签:
【中文标题】在 Wpf C# 中画一条直线【英文标题】:Draw a Straight Line In Wpf C# 【发布时间】:2021-01-02 00:03:09 【问题描述】:您好,我正在我的 Application 中画一条线。我正在使用 Caliburn.Micro MVVM 框架。在我的 DICOM 图像中,我可以使用 Pointer 和 Calculate distance 绘制一条线。我使用 3 个事件 MouseDown、MouseMove 和 MouseUp。我左键单击鼠标,然后如果我释放 I able to Draw 则移动。我的问题是,当我移动鼠标时,有时可能会使用 Graphics.Drawline 画线改变方向,但是当我在最后一点时,它应该是 Straight line 。但是当我移动鼠标时,它的另一点也有不属于这条线的线。请看我做了什么
它应该是一条星线,因为有时我的鼠标移动颜色仍然在那个点。有一个著名的 DICOM Viewer App Name Radiant Here you can see 线是直的。 这是我的代码
<Image Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="4"
x:Name="DIIMGFINAL" cal:Message.Attach="[Event MouseDown] = [Action MDownCalCulateDistance($source, $eventArgs)];
[Event MouseMove] = [Action MMoveCalCulateDistance($source, $eventArgs)];
[Event MouseUp] = [Action MUpCalCulateDistance($source, $eventArgs)]">
</Image>
这是我在 ViewModel 类中的 C# 代码。这是 MouseDown 事件
public void MDownCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
if (!(sender is System.Windows.Controls.Image)) return;
_diIMGTemp = DIIMGFINAL;
if (_firstPoint.X == 0 && _firstPoint.Y == 0)
System.Windows.Point px1 = e.GetPosition((System.Windows.Controls.Image)sender);
_firstPoint = px1;
if (_secondPoint.X != 0 && _secondPoint.Y != 0)
System.Drawing.Bitmap drawbitmap = BitmapImage2Bitmap(DIIMGPrimary);
Graphics g;
using (g = Graphics.FromImage(drawbitmap))
g.DrawLine(Pens.Red, Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y), Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y));
g.Dispose();
Convert_BitMap_BitImage(drawbitmap);
DIIMGFINAL = DIIMGPrimary;
var geometry = new FrameGeometry(DicomDataSet);
var patientCoord1 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y)));
var patientCoord2 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y)));
double distanceInMM = patientCoord1.Distance(patientCoord2);
DisTanceInMM = distanceInMM;
//_firstPoint = new System.Windows.Point(0, 0);
//_secondPoint= new System.Windows.Point(0, 0);
// _isClicked = false;
这是 MouseUp 事件..
public void MUpCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
_firstPoint = new System.Windows.Point(0, 0);
_secondPoint = new System.Windows.Point(0, 0);
最后一个是鼠标移动事件。
public void MMoveCalCulateDistance(object sender, System.Windows.Input.MouseEventArgs e)
if (!(sender is System.Windows.Controls.Image)) return;
System.Windows.Point px = e.GetPosition((System.Windows.Controls.Image)sender);
XCoordinate = px.X;
YCoordinate = px.Y;
// if (_isClicked == false) return;
// MousePoint
if ((_firstPoint.X == 0 && _firstPoint.Y == 0))
return;
else
System.Windows.Point px2 = e.GetPosition((System.Windows.Controls.Image)sender);
_secondPoint = px2;
System.Drawing.Bitmap drawbitmap = BitmapImage2Bitmap(DIIMGPrimary);
Graphics g;
// g.Clear();
using (g = Graphics.FromImage(drawbitmap))
g.DrawLine(Pens.Red, Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y), Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y));
Convert_BitMap_BitImage(drawbitmap);
DIIMGFINAL = DIIMGPrimary;
var geometry = new FrameGeometry(DicomDataSet);
var patientCoord1 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_firstPoint.X), Convert.ToInt32(_firstPoint.Y)));
var patientCoord2 = geometry.TransformImagePointToPatient(new Point2(Convert.ToInt32(_secondPoint.X), Convert.ToInt32(_secondPoint.Y)));
double distanceInMM = patientCoord1.Distance(patientCoord2);
DisTanceInMM = distanceInMM;
请帮助我提前致谢。对不起,冗长的问题。
【问题讨论】:
在每次鼠标移动时从 BitmapSource 转换为 Bitmap 并返回看起来非常低效。为什么不简单地在图像顶部的画布中绘制一条线?然后在鼠标向上修改位图。 感谢您的回答。您在 Canvas 和该图像中提出建议。我使用 bitmapImage 显示图像。因此,如果我想绘制,我将 bitmapimage 转换为 bitmap,而不是在 bitmap 中绘制然后 bitmapimage @Clemens 你能给我一些示例代码怎么做意味着 像这样 ***.com/a/63890185/1136211 谢谢@Clemens 我正在尝试这样做 【参考方案1】:您可能不应该直接在图像上绘图。这是非常低效的,而且你也会遇到你遇到的问题。更好的方法是创建带有线条和其他图形的叠加层,请参阅问题how to bind lines to a canvas,了解如何执行此操作的示例。
如果您将项目控件和图像放在同一个网格中,则项目控件应该像叠加层一样工作。即
<Grid>
<Image>
<!--... -->
</Image>
<ItemsControl ItemsSource="Binding Lines">
<!--...-->
</ItemsControl>
</Grid>
您可以对位图叠加使用相同的方法,但这比让 wpf 为您绘制图元效率低。
【讨论】:
我可以从该图像中删除行吗 @rifat Murtuza 使用绑定的要点之一是添加/删除/移动行相当容易,所以是的。 谢谢 好的,我正在尝试这样做。 但是@JonasH 我应该如何使用以上是关于在 Wpf C# 中画一条直线的主要内容,如果未能解决你的问题,请参考以下文章