My work to create a line is:

XAML code

<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>

Code behind

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;
}

With this work I am able to create a straight line over an image and save the work as a png file. what i need is to be able to draw line with a traingle at the end of the line drawn,

Work i tried:

line.StrokeEndLineCap = PenLineCap.Triangle;

but still a simple line drawn and not a line with an arrowcap as a triangle

other thing which i am not able to figure out is how to draw a line only in XY direction i.e.

example

if the user tries to draw a line in XZ or YZ direction it should not be possible.

Any kind of help is appreciated Thank you

1

There are 1 best solutions below

1
dear_vv On

The lines you see are not Line objects. In fact, they are actually the ink strokes displayed in the InkCanvas control area. Those pointer events you registered for generating lines have no effect, such as StartLine, ContinueLine, CompleteLine. The line object is empty.

It is difficult to add linecap to the ‘line’ in InkCanvas, because it is not a line, it is an ink stroke path. I suggest you could do this through WriteableBitmap and Win2D instead of InkCanvas. You can treat the bitmap as a background layer and draw something on it, such as a line with linecap, and then output all the layers to a new WriteableBitmap. Please refer to this document to get more info.