首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在C#中使用画布创建线条图?另外,我希望这条线只画在XY方向,而不是在XZ或YZ方向。

如何在C#中使用画布创建线条图?另外,我希望这条线只画在XY方向,而不是在XZ或YZ方向。
EN

Stack Overflow用户
提问于 2021-03-16 22:22:27
回答 1查看 64关注 0票数 0

我创建一条线的工作是:

XAML代码

代码语言:javascript
复制
<Viewbox x:Name="Img_VB"
         HorizontalAlignment="Center" 
         VerticalAlignment="Top" 
         Stretch="Uniform">
    <ScrollViewer x:Name="rootScrollViewer" 
                  ZoomMode="Enabled" MaxZoomFactor="5" MinZoomFactor="0.5"
                  HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto"
                  VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
        <Grid x:Name="img_grid" 
          Width="600"
          Height="800" 
          Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" 
          ManipulationMode="Scale">
            <Image 
               x:Name="RoomPlan_Img" 
               VerticalAlignment="Stretch" 
               HorizontalAlignment="Stretch"
               Stretch="Uniform" 
               Height="800" 
               ManipulationMode="Scale">
            </Image>
            <Canvas x:Name="selectionCanvas" 
                Width="600" 
                Background="Transparent" 
                Height="800" >
            </Canvas>
            <InkCanvas x:Name="inker" />
            <InkToolbar x:Name="img_inktoolbar" 
                    InitialControls="None"
                    TargetInkCanvas="{x:Bind inker}" 
                    VerticalAlignment="Top" >
            </InkToolbar>
        </Grid>
    </ScrollViewer>
</Viewbox>

代码在中的应用

代码语言:javascript
复制
public RoomPlanEditCD()
{
    this.InitializeComponent();

    inker.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch;
    inker.InkPresenter.UnprocessedInput.PointerPressed += StartLine;
    inker.InkPresenter.UnprocessedInput.PointerMoved += ContinueLine;
    inker.InkPresenter.UnprocessedInput.PointerReleased += CompleteLine;
    inker.InkPresenter.InputProcessingConfiguration.RightDragAction = InkInputRightDragAction.LeaveUnprocessed;
}

private void StartLine(InkUnprocessedInput sender, PointerEventArgs args)
{
    line = new Line();
    line.X1 = args.CurrentPoint.RawPosition.X;
    line.Y1 = args.CurrentPoint.RawPosition.Y;
    line.X2 = args.CurrentPoint.RawPosition.X;
    line.Y2 = args.CurrentPoint.RawPosition.Y;

    line.Stroke = new SolidColorBrush(Colors.Black);
    line.StrokeThickness = 2;
    selectionCanvas.Children.Add(line);
}

private void ContinueLine(InkUnprocessedInput sender, PointerEventArgs args)
{
    line.X2 = args.CurrentPoint.RawPosition.X;
    line.Y2 = args.CurrentPoint.RawPosition.Y;
}

private void CompleteLine(InkUnprocessedInput sender, PointerEventArgs args)
{
    List<InkPoint> points = new List<InkPoint>();
    InkStrokeBuilder builder = new InkStrokeBuilder();

    InkPoint pointOne = new InkPoint(new Point(line.X1, line.Y1), 0.5f);
    points.Add(pointOne);
    InkPoint pointTwo = new InkPoint(new Point(line.X2, line.Y2), 0.5f);
    points.Add(pointTwo);
    InkStroke stroke = builder.CreateStrokeFromInkPoints(points, System.Numerics.Matrix3x2.Identity);
    InkDrawingAttributes ida = inker.InkPresenter.CopyDefaultDrawingAttributes();
    stroke.DrawingAttributes = ida;
    inker.InkPresenter.StrokeContainer.AddStroke(stroke);
    selectionCanvas.Children.Remove(line);
}

private async void ChooseFileClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
    //some code to pick a file create a stream of it and show it in the Image box

    RoomPlan_Img.Source = bmpimage;
    _ = await ShowAsync();
}

private async void SaveEditedWorkClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
    img_inktoolbar.Visibility = Visibility.Collapsed;
    RenderTargetBitmap bitmap = new RenderTargetBitmap();
    await bitmap.RenderAsync(img_grid);
    var pixelBuffer = await bitmap.GetPixelsAsync();
    byte[] pixels = pixelBuffer.ToArray();
    var displayInformation = DisplayInformation.GetForCurrentView();
    StorageFolder pictureFolder = KnownFolders.SavedPictures;
    var file = await pictureFolder.CreateFileAsync("test2.png", CreationCollisionOption.ReplaceExisting);
    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                             BitmapAlphaMode.Ignore,
                             (uint)bitmap.PixelWidth,
                             (uint)bitmap.PixelHeight,
                             displayInformation.RawDpiX,
                             displayInformation.RawDpiY,
                             pixels);
        await encoder.FlushAsync();
    }
    inker.InkPresenter.StrokeContainer.Clear();
    RoomPlan_Img.Source = null;
    img_inktoolbar.Visibility = Visibility.Visible;
}

通过这项工作,我能够在图像上创建一条直线,并将工作保存为png文件。我需要的是能在画线的末尾画一条线,

我试过的工作:

代码语言:javascript
复制
line.StrokeEndLineCap = PenLineCap.Triangle;

但仍然是一条简单的线,而不是一条以箭帽作为三角形的线。

还有一件事我不知道,那就是如何只在XY方向画一条线。

如果用户试图在XZ或YZ方向绘制一条线,则不应该能够这样做。

任何帮助都是非常感谢的谢谢

EN

回答 1

Stack Overflow用户

发布于 2021-03-17 07:15:28

您看到的线条不是Line对象。实际上,它们实际上是显示在InkCanvas控件区域中的墨迹笔画。为生成行注册的指针事件没有任何效果,例如StartLine、ContinueLine、CompleteLine。行对象为空。

很难在InkCanvas中的“行”中添加linecap,因为它不是一行,而是墨水笔画路径。我建议您可以通过WriteableBitmap和Win2D而不是InkCanvas来实现这一点。您可以将位图看作一个背景层,并在其上绘制一些东西,例如用linecap绘制一行,然后将所有层输出到一个新的WriteableBitmap中。请参考本文件获取更多信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66664268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档