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