问题
I've got a simple demo application that uses an image as the background of an InkCanvas and I scale the strokes when the display of the image is resized so that they remain in the same place relative to the image. Since you can draw -> resize -> draw -> resize -> draw this means I have to scale each stroke a different amount each time by assigning the PointTransform on each stroke.
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));
}
This resizes the length of the strokes perfectly well. However, it does nothing to the thickness of the strokes. This is even more evident when you use a thick or non-uniform pen (eg the highlighter pen).
These link to two screen clips which show the results. Full-screen - https://1drv.ms/i/s!ArHMZAt1svlBiZZDfrxFqyGU1bJ6MQ Smaller window - https://1drv.ms/i/s!ArHMZAt1svlBiZZCqHHYaISPfWMMpQ
Any ideas on how I can resize the thickness of the strokes?
回答1:
Apply a ScaleTransform to the InkCanvas control. That'll take care of scaling the ink stroke,the stroke locations and the background image. Essentially the transform applies to everything contained in the InkCanvas. No need to use the Matrix with the 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>
Code
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;
}
Screenshots
Scaled 100%
Scaled 60%
回答2:
Scaling the InkCanvas doesn't always fix the problem especially if you are wanting to save the scaled ink into a gif image file.
Apparently an InkStroke's PointTransform only transforms the location of the stroke's points, but not the size of the PenTip used to draw the stroke. (Not documented anywhere that I can find, but discovered by trial and error. The name 'PointTransform' is a bit of a clue)
So as well as applying your scaling factor to the PointTransform, you also have to scale the PenTip as follows (modification to your original code):
float thisPointScale = thisScale * stroke.PointTransform.M11;
stroke.PointTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
stroke.DrawingAttributes.PenTipTransform = Matrix3x2.CreateScale(new Vector2(thisPointScale));
Hope this helps someone...
回答3:
To resize the thickness of the strokes you have to change the Size property of the DrawingAttributes. PenTipTransform doesn't work for pencil - it throws an exception.
The point is that you cannot set the DrawingAttributes property of the stroke directly: https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.inking.inkdrawingattributes
Here is example how to get this:
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;
}
Complete example: https://github.com/ycherkes/ScaledInks
来源:https://stackoverflow.com/questions/43106842/scaling-inkstrokes-in-uwp