在 UWP 中缩放 InkStrokes
Scaling InkStrokes in UWP
我有一个简单的演示应用程序,它使用图像作为 InkCanvas 的背景,并且在调整图像显示大小时缩放笔划,以便它们相对于图像保持在同一位置。由于您可以绘制 -> 调整大小 -> 绘制 -> 调整大小 -> 绘制,这意味着我必须通过在每个笔划上分配 PointTransform 来每次缩放每个笔划不同的量。
float thisScale = (float)(scale / _prevScale);
foreach (InkStroke stroke in myCanvas.InkPresenter.StrokeContainer.GetStrokes())
{
float thisPointScale = thisScale * stroke.PointTransform.M11;
stroke.PointTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
}
这可以很好地调整笔画的长度。但是,它对笔画的粗细没有任何影响。当您使用粗或不均匀的笔(例如荧光笔)时,这一点更加明显。
这些 link 到显示结果的两个屏幕剪辑。
全屏 - https://1drv.ms/i/s!ArHMZAt1svlBiZZDfrxFqyGU1bJ6MQ
较小 window - https://1drv.ms/i/s!ArHMZAt1svlBiZZCqHHYaISPfWMMpQ
关于如何调整笔画粗细的任何想法?
将 ScaleTransform 应用于 InkCanvas 控件。这将负责缩放墨迹笔划、笔划位置和背景图像。本质上,转换适用于 InkCanvas 中包含的所有内容。无需将 Matrix 与 StrokeCollection 一起使用。
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Red Highlighter "
x:Name="InkRedAttributesButton"
Click="InkRedAttributesButton_Click" />
<Button Content="Blue Highlighter "
x:Name="InkBlueAttributesButton"
Click="InkBlueAttributesButton_Click" />
<Button Content="Scale Down"
x:Name="ScaleDownButton"
Click="ScaleDownButton_Click" />
<Button Content="Scale Up"
x:Name="ScaleUpButton"
Click="ScaleUpButton_Click" />
</StackPanel>
<InkCanvas x:Name="myCanvas"
Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<InkCanvas.Background>
<ImageBrush ImageSource="/SO_Questions;component/Images/Star02.jpg"
Stretch="Fill" />
</InkCanvas.Background>
<InkCanvas.RenderTransform>
<ScaleTransform x:Name="InkCanvasScaleTransform" />
</InkCanvas.RenderTransform>
</InkCanvas>
</Grid>
代码
private void ScaleUpButton_Click(object sender, RoutedEventArgs e) {
InkCanvasScaleTransform.ScaleX += .2;
InkCanvasScaleTransform.ScaleY += .2;
}
private void ScaleDownButton_Click(object sender, RoutedEventArgs e) {
InkCanvasScaleTransform.ScaleX -= .2;
InkCanvasScaleTransform.ScaleY -= .2;
}
private void InkRedAttributesButton_Click(object sender, RoutedEventArgs e) {
DrawingAttributes inkAttributes = new DrawingAttributes();
inkAttributes.Height = 12;
inkAttributes.Width = 12;
inkAttributes.Color = Colors.Red;
inkAttributes.IsHighlighter = true;
myCanvas.DefaultDrawingAttributes = inkAttributes;
}
private void InkBlueAttributesButton_Click(object sender, RoutedEventArgs e) {
DrawingAttributes inkAttributes = new DrawingAttributes();
inkAttributes.Height = 12;
inkAttributes.Width = 12;
inkAttributes.Color = Colors.Blue;
inkAttributes.IsHighlighter = true;
myCanvas.DefaultDrawingAttributes = inkAttributes;
}
截图
缩放 100%
缩放 60%
缩放 InkCanvas 并不总能解决问题,尤其是当您想要将缩放后的墨迹保存到 gif 图像文件中时。
显然,InkStroke 的 PointTransform 仅变换笔划点的位置,但不变换用于绘制笔划的 PenTip 的大小。 (在我能找到的任何地方都没有记录,但通过反复试验发现。名称 'PointTransform' 有点线索)
因此,除了将缩放因子应用于 PointTransform 之外,您还必须按如下方式缩放 PenTip(对原始代码的修改):
float thisPointScale = thisScale * stroke.PointTransform.M11;
stroke.PointTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
stroke.DrawingAttributes.PenTipTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
希望这对某人有所帮助...
要调整笔画的粗细,您必须更改 DrawingAttributes 的大小 属性。 PenTipTransform 不适用于铅笔 - 它会引发异常。
重点是你不能直接设置DrawingAttributes属性笔画: https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.inking.inkdrawingattributes
这里是如何获得这个的例子:
static IEnumerable<InkStroke> GetScaledStrokes(IEnumerable<InkStroke> source, float scale)
{
var scaleMatrix = Matrix3x2.CreateScale(scale);
var resultStrokes = source.Select(x => x.Clone()).ToArray();
foreach (var inkStroke in resultStrokes)
{
inkStroke.PointTransform = scaleMatrix;
var da = inkStroke.DrawingAttributes;
var daSize = da.Size;
daSize.Width = daSize.Width * scale;
daSize.Height = daSize.Height * scale;
da.Size = daSize;
inkStroke.DrawingAttributes = da;
}
return resultStrokes;
}
我有一个简单的演示应用程序,它使用图像作为 InkCanvas 的背景,并且在调整图像显示大小时缩放笔划,以便它们相对于图像保持在同一位置。由于您可以绘制 -> 调整大小 -> 绘制 -> 调整大小 -> 绘制,这意味着我必须通过在每个笔划上分配 PointTransform 来每次缩放每个笔划不同的量。
float thisScale = (float)(scale / _prevScale);
foreach (InkStroke stroke in myCanvas.InkPresenter.StrokeContainer.GetStrokes())
{
float thisPointScale = thisScale * stroke.PointTransform.M11;
stroke.PointTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
}
这可以很好地调整笔画的长度。但是,它对笔画的粗细没有任何影响。当您使用粗或不均匀的笔(例如荧光笔)时,这一点更加明显。
这些 link 到显示结果的两个屏幕剪辑。 全屏 - https://1drv.ms/i/s!ArHMZAt1svlBiZZDfrxFqyGU1bJ6MQ 较小 window - https://1drv.ms/i/s!ArHMZAt1svlBiZZCqHHYaISPfWMMpQ
关于如何调整笔画粗细的任何想法?
将 ScaleTransform 应用于 InkCanvas 控件。这将负责缩放墨迹笔划、笔划位置和背景图像。本质上,转换适用于 InkCanvas 中包含的所有内容。无需将 Matrix 与 StrokeCollection 一起使用。
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Red Highlighter "
x:Name="InkRedAttributesButton"
Click="InkRedAttributesButton_Click" />
<Button Content="Blue Highlighter "
x:Name="InkBlueAttributesButton"
Click="InkBlueAttributesButton_Click" />
<Button Content="Scale Down"
x:Name="ScaleDownButton"
Click="ScaleDownButton_Click" />
<Button Content="Scale Up"
x:Name="ScaleUpButton"
Click="ScaleUpButton_Click" />
</StackPanel>
<InkCanvas x:Name="myCanvas"
Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<InkCanvas.Background>
<ImageBrush ImageSource="/SO_Questions;component/Images/Star02.jpg"
Stretch="Fill" />
</InkCanvas.Background>
<InkCanvas.RenderTransform>
<ScaleTransform x:Name="InkCanvasScaleTransform" />
</InkCanvas.RenderTransform>
</InkCanvas>
</Grid>
代码
private void ScaleUpButton_Click(object sender, RoutedEventArgs e) {
InkCanvasScaleTransform.ScaleX += .2;
InkCanvasScaleTransform.ScaleY += .2;
}
private void ScaleDownButton_Click(object sender, RoutedEventArgs e) {
InkCanvasScaleTransform.ScaleX -= .2;
InkCanvasScaleTransform.ScaleY -= .2;
}
private void InkRedAttributesButton_Click(object sender, RoutedEventArgs e) {
DrawingAttributes inkAttributes = new DrawingAttributes();
inkAttributes.Height = 12;
inkAttributes.Width = 12;
inkAttributes.Color = Colors.Red;
inkAttributes.IsHighlighter = true;
myCanvas.DefaultDrawingAttributes = inkAttributes;
}
private void InkBlueAttributesButton_Click(object sender, RoutedEventArgs e) {
DrawingAttributes inkAttributes = new DrawingAttributes();
inkAttributes.Height = 12;
inkAttributes.Width = 12;
inkAttributes.Color = Colors.Blue;
inkAttributes.IsHighlighter = true;
myCanvas.DefaultDrawingAttributes = inkAttributes;
}
截图
缩放 100%
缩放 60%
缩放 InkCanvas 并不总能解决问题,尤其是当您想要将缩放后的墨迹保存到 gif 图像文件中时。
显然,InkStroke 的 PointTransform 仅变换笔划点的位置,但不变换用于绘制笔划的 PenTip 的大小。 (在我能找到的任何地方都没有记录,但通过反复试验发现。名称 'PointTransform' 有点线索)
因此,除了将缩放因子应用于 PointTransform 之外,您还必须按如下方式缩放 PenTip(对原始代码的修改):
float thisPointScale = thisScale * stroke.PointTransform.M11;
stroke.PointTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
stroke.DrawingAttributes.PenTipTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
希望这对某人有所帮助...
要调整笔画的粗细,您必须更改 DrawingAttributes 的大小 属性。 PenTipTransform 不适用于铅笔 - 它会引发异常。
重点是你不能直接设置DrawingAttributes属性笔画: https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.inking.inkdrawingattributes
这里是如何获得这个的例子:
static IEnumerable<InkStroke> GetScaledStrokes(IEnumerable<InkStroke> source, float scale)
{
var scaleMatrix = Matrix3x2.CreateScale(scale);
var resultStrokes = source.Select(x => x.Clone()).ToArray();
foreach (var inkStroke in resultStrokes)
{
inkStroke.PointTransform = scaleMatrix;
var da = inkStroke.DrawingAttributes;
var daSize = da.Size;
daSize.Width = daSize.Width * scale;
daSize.Height = daSize.Height * scale;
da.Size = daSize;
inkStroke.DrawingAttributes = da;
}
return resultStrokes;
}