Как создать обводку с помощью inkcanvas в С#? также я хочу, чтобы линия рисовалась только в направлении XY, а не в направлении XZ или YZ

Моя работа по созданию линии:

XAML-код

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

Код

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. что мне нужно, так это иметь возможность рисовать линию с трейглом в конце нарисованной линии,

Работа, которую я пробовал:

line.StrokeEndLineCap = PenLineCap.Triangle;

но все же простая нарисованная линия, а не линия со стрелкой в ​​виде треугольника

другая вещь, которую я не могу понять, это как рисовать линию только в направлении XY, т.е.

пример

если пользователь попытается нарисовать линию в направлении XZ или YZ, это будет невозможно.

Любая помощь приветствуется Спасибо


person Faraaz bhilwade    schedule 16.03.2021    source источник


Ответы (1)


Линии, которые вы видите, не являются объектами Line. На самом деле это штрихи пера, отображаемые в области управления InkCanvas. Те события указателя, которые вы зарегистрировали для генерации строк, не действуют, например, StartLine, ContinueLine, CompleteLine. Объект линии пуст.

Добавить штрих к «линии» в InkCanvas сложно, потому что это не линия, а путь росчерка пера. Я предлагаю вам сделать это через WriteableBitmap и Win2D вместо InkCanvas. Вы можете рассматривать растровое изображение как фоновый слой и рисовать на нем что-либо, например, линию с заглавными буквами, а затем выводить все слои в новый WriteableBitmap. Пожалуйста, обратитесь к этот документ, чтобы получить дополнительную информацию.

person Arya Ding - MSFT    schedule 17.03.2021
comment
Эй, спасибо за ваше время. Я уже пробовал этот пример, и он не сработал :( поэтому я использовал описанный выше подход для создания строки с использованием inkcanvas, а также описанный выше подход был довольно маленьким и простым в исполнении по сравнению с примером win2d - person Faraaz bhilwade; 17.03.2021