在 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;
    }

完整示例:https://github.com/ycherkes/ScaledInks