【问题标题】:Scaling InkStrokes in UWP在 UWP 中缩放 InkStrokes
【发布时间】:2017-03-30 01:17:54
【问题描述】:

我有一个简单的演示应用程序,它使用图像作为 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));
}

这可以很好地调整笔画的长度。但是,它对笔画的粗细没有任何影响。当您使用粗笔或不均匀的笔(例如荧光笔)时,这一点会更加明显。

这些链接到显示结果的两个屏幕剪辑。 全屏 - https://1drv.ms/i/s!ArHMZAt1svlBiZZDfrxFqyGU1bJ6MQ 较小的窗口 - https://1drv.ms/i/s!ArHMZAt1svlBiZZCqHHYaISPfWMMpQ

关于如何调整笔画粗细的任何想法?

【问题讨论】:

    标签: c# uwp-xaml inkcanvas


    【解决方案1】:

    将 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%

    【讨论】:

    • 谢谢沃尔特。我现在会玩这个,看看它是否也可以将图像用作画布背景。我实际上是在“裁剪”画布大小以匹配真实图像尺寸而不是图像控件的边界框(因为在横向监视器上全屏显示的纵向图像周围有很多空白空间)。顺便说一句,图片很棒:)
    • 它似乎有一些优点和一些缺点。我不再需要像缩放变换那样调整画布大小。
    • ...(继续)尽管工具栏存在问题,因为画布的缩放没有反映在笔的大小中。我必须添加一个不显示示例笔大小的自定义工具栏。
    【解决方案2】:

    缩放 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));
    

    希望这对某人有所帮助...

    【讨论】:

    • 我最近遇到了这个问题。笔画点正在移动,但笔画的宽度无法正确缩放。但是,当我实施您的解决方案时。 PenTipTransform 不会改变。
    【解决方案3】:

    要调整笔画的粗细,您必须更改 DrawingAttributes 的 Size 属性。 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多