Чернильные штрихи маркера не отображаются на холсте

Я пытаюсь реализовать функции рукописного ввода с помощью «InkToolbar» и «InkCanvas». Я также хочу иметь доступ к мазкам тушью, поэтому я также активировал пользовательскую сушку на InkCanvas.

Штрихи пера и карандашные мазки правильно отображаются на элементе управления холстом, но штрихи маркера не отображаются (не видны) на элементе управления холстом.

Я также пробовал эти решения, но проблема все еще существует, Сохранить Windows Ink как прозрачное изображение PNG — отсутствуют штрихи маркера

XAML-код

<Grid x:Name="container" Background="#FF282828">
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <InkToolbar x:Name="inkToolbar" InitialControls="None" Grid.Row="0">
        <InkToolbarBallpointPenButton />
        <InkToolbarPencilButton />
        <InkToolbarHighlighterButton />
        <InkToolbarEraserButton />
    </InkToolbar>
    <ScrollViewer ZoomMode="Enabled" Background="DarkGray" Grid.Row="1" x:Name="scrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" MinZoomFactor="0.5" Height="Auto">
        <Grid x:Name="viewport" VerticalAlignment="Top">
            <Border x:Name="viewportBorder" Background="White" BorderThickness="15, 15, 15, 15" BorderBrush="#FF353334" />
        </Grid>
    </ScrollViewer>
</Grid>

Код позади

public sealed partial class MainPage : Page
{
    private Canvas SelectCanvas;
    private InkCanvas InkCanvas;
    private CanvasControl CanvasControl;
    private InkSynchronizer InkSynchronizer;
    private List<InkStrokeContainer> InkStrokeContainers = new List<InkStrokeContainer>();

    public MainPage()
    {
        this.InitializeComponent();
        InitViweport().GetAwaiter();
    }

    private async Task InitViweport()
    {
        FileOpenPicker openPicker = new FileOpenPicker
        {
            SuggestedStartLocation = PickerLocationId.PicturesLibrary,
            ViewMode = PickerViewMode.Thumbnail
        };

        // Filter to include a sample subset of file types.
        openPicker.FileTypeFilter.Clear();
        openPicker.FileTypeFilter.Add(".bmp");
        openPicker.FileTypeFilter.Add(".png");
        openPicker.FileTypeFilter.Add(".jpeg");
        openPicker.FileTypeFilter.Add(".jpg");

        var file = await openPicker.PickSingleFileAsync();

        if (file != null)
        {
            // Open a stream for the selected file.
            IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);

            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(fileStream);

            viewport.Width = bitmapImage.PixelWidth;
            viewport.Height = bitmapImage.PixelHeight;

            using (var stream = await file.OpenReadAsync())
            {
                WriteableBitmap bitmap = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
                await bitmap.SetSourceAsync(stream);

                var image = new Image();
                image.Source = bitmap;

                viewport.Children.Add(image);
            }
        }

        AddCanvases();
    }

    private void AddCanvases()
    {
        SelectCanvas = new Canvas
        {
            Height = viewport.Height,
            Width = viewport.Width
        };

        InkCanvas = new InkCanvas
        {
            Width = viewport.Width,
            Height = viewport.Height
        };
        inkToolbar.TargetInkCanvas = InkCanvas;

        CanvasControl = new CanvasControl()
        {
            Height = viewport.Height,
            Width = viewport.Width,
            Background = new SolidColorBrush(Colors.Transparent)
        };
        CanvasControl.Draw += CanvasControlDraw;

        InkSynchronizer = InkCanvas.InkPresenter.ActivateCustomDrying();
        InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch;

        InkCanvas.InkPresenter.StrokesCollected += InkPresenter_StrokesCollected;

        Canvas.SetZIndex(InkCanvas, 5);
        Canvas.SetZIndex(SelectCanvas, 2);

        viewport.Children.Add(SelectCanvas);
        viewport.Children.Add(CanvasControl);
        viewport.Children.Add(InkCanvas);
    }

    private void CanvasControlDraw(CanvasControl sender, CanvasDrawEventArgs args) => DrawInk(args.DrawingSession);

    private void DrawInk(CanvasDrawingSession session)
    {
        foreach (var container in InkStrokeContainers)
        {
            var strokes = container.GetStrokes();

            using (var list = new CanvasCommandList(session))
            {
                using (var listSession = list.CreateDrawingSession())
                    listSession.DrawInk(strokes);

                using (var shadowEffect = new ShadowEffect { ShadowColor = Colors.DarkGray, Source = list })
                    session.DrawImage(shadowEffect, new Vector2(2, 2));
            }

            session.DrawInk(strokes);
        }
    }

    private void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
    {
        var strokeContainer = new InkStrokeContainer();
        strokeContainer.AddStrokes(from stroke in args.Strokes select stroke.Clone());
        InkStrokeContainers.Add(strokeContainer);
        InkSynchronizer.EndDry();

        CanvasControl.Invalidate();
    }
}

Я не уверен, в чем здесь проблема. Может ли кто-нибудь указать мне правильное направление? Любая помощь горячо приветствуется.

Спасибо


person Madushan Amarasinghe    schedule 24.03.2021    source источник
comment
Я предполагаю, что это может иметь какое-то отношение к фону поверхности рисования, на котором нарисованы чернила маркера, попытался установить фон управления холстом таким же, как изображение, используя кисть изображения Background = new ImageBrush { ImageSource = image.Source }, но все равно не повезло.   -  person Madushan Amarasinghe    schedule 24.03.2021
comment
Один обходной путь, который я нашел, заключался в установке чистого цвета элемента управления холстом, такого как CanvasControl = new CanvasControl() { Height = viewport.Height, Width = viewport.Width, ClearColor = Color.FromArgb(100, 255, 255, 255) };, но он рисует выцветший слой поверх содержимого, что выглядит немного неуместно. Нет ли другого способа сделать это?   -  person Madushan Amarasinghe    schedule 24.03.2021
comment
Я проверил код, предоставленный вами. В коде InkSynchronizer.EndDry(); возникает исключение System.InvalidOperationException. Я комментирую строку кода, и тогда приложение может работать нормально. В моем тесте чернила highliter могли отображаться на выбранном изображении. Меня смущает предложение «но штрихи маркера не отображаются (не видны) в элементе управления холстом». Не могли бы вы подробно описать ожидаемое поведение?   -  person YanGu    schedule 25.03.2021
comment
Забавно, я поместил в вопрос код, который был связан только со сценарием рисования тушью, и пропустил, чтобы поставить InkSynchronizer.BeginDry(); в вопросе. Я прокомментировал строку EndDry, как и вы, и это привело к тому поведению, которое я хотел. Я предполагаю, что использование InkSynchronizer не устранило проблему. Можете ли вы опубликовать ответ, чтобы я мог пометить его как исправленное? @YanGu-MSFT   -  person Madushan Amarasinghe    schedule 25.03.2021


Ответы (1)


Я заметил, что вы используете метод InkSynchronizer.EndDry, но не используете метод InkSynchronizer.BeginDry в своем коде. При тестировании в коде InkSynchronizer.EndDry(); происходит System.InvalidOperationException. Затем я комментирую строку кода, и приложение может работать так, как вы и ожидали. А еще я пытаюсь добавить метод InkSynchronizer.BeginDry перед методом InkSynchronizer.EndDry, тоже работает. Поэтому вам может потребоваться удалить использование метода InkSynchronizer.EndDry или добавить использование метода InkSynchronizer.BeginDry в вашем приложении.

person YanGu    schedule 26.03.2021