问题描述
我正在尝试使用“InkToolbar”和“InkCanvas”来实现墨迹书写功能。我也希望能够访问墨水笔划,因此我也在 InkCanvas 上激活了自定义干燥。
钢笔墨水笔划和铅笔墨水笔划在画布控件上正确呈现,但荧光笔笔画未在画布控件上呈现(不可见)。
我也尝试过这些解决方案,但问题仍然存在, Save Windows Ink as transparent PNG image - missing highlighter strokes
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" 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();
}
}
我不确定这里有什么问题。有人可以指出我正确的方向吗?非常感谢任何帮助。
谢谢
解决方法
我注意到您在代码中使用了 InkSynchronizer.EndDry
方法,但没有使用 InkSynchronizer.BeginDry
方法。通过测试,在代码 System.InvalidOperationException
处出现了 InkSynchronizer.EndDry();
。然后我对代码行进行注释,应用程序可以按照您的预期运行良好。而且我还尝试在 InkSynchronizer.BeginDry
方法之前添加 InkSynchronizer.EndDry
方法,它也有效。因此,您可能需要删除 InkSynchronizer.EndDry
方法的用法,或在您的应用中添加 InkSynchronizer.BeginDry
方法的用法。