移动UWP笔触进行屏幕外渲染

时间:2018-08-31 15:44:40

标签: c# uwp uwp-xaml inkcanvas

我正在捕获 InkStrokes ,并且需要在背景中创建笔触的缩放位图图像。无论墨水的边界框有多大,捕获的图像都必须具有统一的大小。

例如,如果在墨水画布上绘制了原始墨水笔划,并且边框的上/左边界是100,100,尺寸是200,200,则我希望墨水从新的渲染位图的0,0开始,即50,50大小(暂时忽略笔划宽度的影响)。

我已经弄清楚了如何缩放笔触(感谢StackOverflow),但是却不知道如何移动笔触。现在,看来我必须创建一个 InkCanvas 大小的位图,渲染缩放的墨水,然后将更大的图像裁剪为正确的大小。

我尝试通过

InkStroke.PointTranslate

var scaleMatrix = Matrix3x2.CreateScale(scale);
scaleMatrix.Translation = -offset; // top/left of ink stroke bounding box
stroke.PointTransform = scaleMatrix;

但是坐标不能正确显示。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您可以通过相乘矩阵来组合变换。这对我有用

var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();

var boundingBox = inkCanvas.InkPresenter.StrokeContainer.BoundingRect;

var matrix1 = Matrix3x2.CreateTranslation((float)-boundingBox.X, (float)-boundingBox.Y);
var matrix2 = Matrix3x2.CreateScale(0.5f);

var builder = new InkStrokeBuilder();
var newStrokeList = new List<InkStroke>();
foreach (var stroke in strokes)
{
    newStrokeList.Add(builder.CreateStrokeFromInkPoints
        (stroke.GetInkPoints(), matrix1 * matrix2));
}

//Add the translated and scaled strokes to the inkcanvas
inkCanvas.InkPresenter.StrokeContainer.AddStrokes(newStrokeList);

答案 1 :(得分:0)

也许我还在做错什么,但看来您不能使用 InkStrokeBuilder.CreateStrokeFromInkPoints 进行多种转换。我尝试了各种组合/方法,但无法使其正常工作。

这是我的解决方法...

 private static IList<InkStroke> GetScaledAndTransformedStrokes(IList<InkStroke> strokeList, float scale)
        {
            var builder = new InkStrokeBuilder();
            var newStrokeList = new List<InkStroke>();
            var boundingBox = strokeList.GetBoundingBox();

            foreach (var singleStroke in strokeList)
            {  
                var translateMatrix = new Matrix(1, 0, 0, 1, -boundingBox.X, -boundingBox.Y);

                var newInkPoints = new List<InkPoint>();
                var originalInkPoints = singleStroke.GetInkPoints();
                foreach (var point in originalInkPoints)
                {
                    var newPosition = translateMatrix.Transform(point.Position);
                    var newInkPoint = new InkPoint(newPosition, point.Pressure, point.TiltX, point.TiltY, point.Timestamp);
                    newInkPoints.Add(newInkPoint);
                }

                var newStroke = builder.CreateStrokeFromInkPoints(newInkPoints, new Matrix3x2(scale, 0, 0, scale, 0, 0));

                newStrokeList.Add(newStroke);
            }

            return newStrokeList;
        }

我最终不得不应用自己的转换变换,然后使用 builder.CreateStrokeFromInkPoints 并应用比例矩阵来获得所需的结果。 GetBoundingBox 是我自己的扩展名:

 public static class RectExtensions
    {
        public static Rect CombineWith(this Rect r, Rect rect)
        {
            var top = (r.Top < rect.Top) ? r.Top : rect.Top;
            var left = (r.Left < rect.Left) ? r.Left : rect.Left;
            var bottom = (r.Bottom < rect.Bottom) ? rect.Bottom : r.Bottom;
            var right = (r.Right < rect.Right) ? rect.Right : r.Right;

            var newRect = new Rect(new Point(left, top), new Point(right, bottom));
            return newRect;
        }
    }