【问题标题】:Scaling Canvas InkStrokes缩放画布 InkStrokes
【发布时间】:2018-05-03 20:46:56
【问题描述】:

我正在用相机拍照,将其用作 InkCanvas 的背景,并让用户在上面绘制。

当用户保存他们的绘图时,我正在缩放绘图以匹配背景中图像的大小。我无法调整原始图像的大小。

但是,在缩放笔划的长度和位置时,宽度不会。 滚动浏览 StackOverflow,我发现有人说您还需要在 InkStroke.DrawingAttributes.PenTipTransformInkStroke.PointTransform 上设置比例,但是当我尝试将值设置为比例时,值不会改变。

原始值 新价值观

任何关于我如何设置这个值的信息,或者其他方式来做同样的事情,我们将不胜感激。

谢谢

界面代码

 <!-- Canvas -->
    <Image Grid.Row="1" x:Name="imgImage" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" SizeChanged="imgImage_SizeChanged"/>

    <InkCanvas Grid.Row="1" x:Name="inkCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" PointerExited="inkCanvas_PointerExited" Visibility="Collapsed">
        <InkCanvas.RenderTransform>
            <ScaleTransform x:Name="inkCanvasScaleTransform" />
        </InkCanvas.RenderTransform>
    </InkCanvas>

编辑 - 更多信息

相机拍摄的图像分辨率为 3264x244,然后用户可以使用画布在图像上绘制,但我无法在屏幕上显示整个图像,因此将其按比例缩小以适应帆布。画布(在本例中)的分辨率为 1012x759。

保存图像后,绘制的位置会按比例放大以匹配图像的完整大小。但笔画的宽度没有。

附:当前未使用 XAML 中的缩放变换。

保存代码

StorageFile inputFile = null;
        inputFile = await StorageFile.GetFileFromPathAsync(_image.fullPath);
        height = (int)inkCanvas.ActualHeight;
        width = (int)inkCanvas.ActualWidth;
        double scalex = 0;
        double scaley = 0;
        double offsety = 0;
        double offsetx = 0;
        double widthscale = 1;
        if (inputFile != null)
        {
            var prop = await inputFile.Properties.GetImagePropertiesAsync();
            offsetx = (double)prop.Width - width;
            offsety = (double)prop.Height - height;
            scalex = ((double)prop.Width - width) / width;
            scaley = ((double)prop.Height - height) / height;
            width = (int)prop.Width;
            height = (int)prop.Height;
            widthscale = 1 + ((scalex * scaley) / 2);
        }

        var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
        List<InkStroke> ExpandedStrokes = new List<InkStroke>();
        foreach (var stroke in strokes)
        {
            InkStroke strk = stroke.Clone();
            Matrix3x2 scaleMatrix = Matrix3x2.CreateScale(1 + (float)scalex, 1 + (float)scaley);
            strk.PointTransform = scaleMatrix;
            strk.DrawingAttributes.PenTipTransform = scaleMatrix;
            ExpandedStrokes.Add(strk);
        }

        StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        CanvasDevice device = CanvasDevice.GetSharedDevice();
        CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, width, height, 96);
        using (var ds = renderTarget.CreateDrawingSession())
        {
            ds.Clear(Colors.White);
            if (inputFile != null)
            {
                using (CanvasBitmap image = await CanvasBitmap.LoadAsync(device, inputFile.Path, 96))
                {
                    ds.DrawImage(image);
                }
            }
            ds.DrawInk(ExpandedStrokes);
        }
        using (var fileStream = await inputFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Jpeg, 1f);
        }

PenTip 的刻度可能不正确,但只是试图让它做出改变。

示例图像

缩放前 (1012x759)

缩放后 (3264x2448)

【问题讨论】:

  • 您能否提供更多的代码并阐明您想要达到的实际效果?如果用户在图像上画笔画,他们会想在那里画,为什么要再次缩放?那么缩放绘图以匹配图像大小的含义是什么?如果您能提供最低限度的样本来帮助我理解您的问题,那就更好了。

标签: c# canvas uwp inkcanvas


【解决方案1】:

InkStroke.PointTransform 用于调整笔画的长度,它不会缩放笔画的粗细。如果要显示相应宽度的笔划,可以使用InkCanvas.RenderTransform,并设置它的ScaleX和ScaleY,但这不会影响Stroke的粗细效果,它只是调整InkCanvas的大小,使Strokes看起来像被缩放。似乎没有属性可以改变在图像上绘制的笔触的实际粗细。

其实,当你把一张照片作为背景图片放到Image控件中,然后用户就可以在图片上绘图了,你也许可以让用户选择不同配置的Pen进行绘图。用户画完后,会用笔画保存图片,这应该是他们想要的效果。也就是说,我们用钢笔在小图上画,只要确定笔画在正确的位置,如果图片变大,笔画应该会自动改变,我认为不应该改变笔画再次缩放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-28
    • 2011-10-10
    • 2017-10-16
    • 1970-01-01
    • 2016-08-26
    • 2013-12-31
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多