Rotate also resizes?
I have this xaml
<Image Width="240" Height="240">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
开发者_运维知识库 <DrawingGroup>
<DrawingGroup>
<DrawingGroup.Transform>
<TransformGroup>
<RotateTransform Angle="-15" CenterX="120" CenterY="120" />
<TranslateTransform Y="-20" />
</TransformGroup>
</DrawingGroup.Transform>
<ImageDrawing ImageSource="Images\pNxVK.png" Rect="0,0,240,240" />
</DrawingGroup>
<DrawingGroup.ClipGeometry>
<EllipseGeometry Center="120,120" RadiusX="60" RadiusY="60" />
</DrawingGroup.ClipGeometry>
</DrawingGroup>
<DrawingGroup>
<DrawingGroup>
<!--<DrawingGroup.Transform>
<RotateTransform Angle="-15" CenterX="120" CenterY="120" />
</DrawingGroup.Transform>-->
<ImageDrawing ImageSource="Images\zUr8D.png" Rect="0,0,240,240" />
</DrawingGroup>
<ImageDrawing ImageSource="Images\XPZW9.png" Rect="0,0,240,240" />
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
The result of that xaml is (Correct size)
If I uncomment the rotate transform in the xaml above i get this (Wrong size)
The drawings are rectangles. And a rotated rectangle has bigger bounding box than a non-rotated one, so it has to be scaled to fit the original boundaries.
You can resolve this by specifying ClipGeometry of the outermost DrawingGroup - just clip it to the original bounds.
<DrawingGroup.ClipGeometry>
<RectangleGeometry Rect="0 0 240 240" />
</DrawingGroup.ClipGeometry>
If its not working when we do it in xaml, maybe it will work from code:
Xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock Text="Rotate:" />
<Slider Minimum="-360" Maximum="360" Value="{Binding ElementName=CrossHair, Path=Rotate, Mode=TwoWay}" />
<TextBlock Text="TranslateX:" />
<Slider Minimum="-200" Maximum="200" Value="{Binding ElementName=CrossHair, Path=TranslateX, Mode=TwoWay}" />
<TextBlock Text="TranslateY:" />
<Slider Minimum="-200" Maximum="200" Value="{Binding ElementName=CrossHair, Path=TranslateY, Mode=TwoWay}" />
<local:CrossHair Width="240" Height="240" x:Name="CrossHair" />
</StackPanel>
</Window>
Code-behind:
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class CrossHair : FrameworkElement
{
public double TranslateX
{
get { return (double)GetValue(TranslateXProperty); }
set { SetValue(TranslateXProperty, value); }
}
public static readonly DependencyProperty TranslateXProperty = DependencyProperty.Register("TranslateX", typeof(double), typeof(CrossHair), new UIPropertyMetadata(0.0, PropertyChangedCallback));
public double TranslateY
{
get { return (double)GetValue(TranslateYProperty); }
set { SetValue(TranslateYProperty, value); }
}
public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register("TranslateY", typeof(double), typeof(CrossHair), new UIPropertyMetadata(-20.0, PropertyChangedCallback));
public double Rotate
{
get { return (double)GetValue(RotateProperty); }
set { SetValue(RotateProperty, value); }
}
// This will result in an OnRender call.
public static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = d as FrameworkElement;
if (element != null)
element.InvalidateVisual();
}
public static readonly DependencyProperty RotateProperty = DependencyProperty.Register("Rotate", typeof(double), typeof(CrossHair), new UIPropertyMetadata(-15.0, PropertyChangedCallback));
protected override void OnRender(DrawingContext ctx)
{
base.OnRender(ctx);
double renderWidht = this.ActualWidth;
double renderHeight = this.ActualHeight;
//Debug Rectangle, you should comment it.
//ctx.DrawRectangle(Brushes.Black, new Pen(Brushes.Black, 1), new Rect(0, 0, renderWidht, renderHeight));
// First Layer: clipped background.
ctx.PushClip(new EllipseGeometry(new Point(renderWidht / 2.0, renderHeight / 2.0), renderWidht / 4.0, renderHeight / 4.0));
ctx.PushTransform(new TransformGroup()
{
Children = new TransformCollection(2)
{
new TranslateTransform(TranslateX, TranslateY),
new RotateTransform(Rotate, renderWidht / 2.0, renderHeight / 2.0)
}
});
ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/pNxVK.png")), new Rect(0, 0, renderWidht, renderHeight));
ctx.Pop();// Pop the clipping
ctx.Pop();// Pop the translate
// 2nd Layer:
ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/XPZW9.png")), new Rect(0, 0, renderWidht, renderHeight));
// 3rd Layer:
ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/zUr8D.png")), new Rect(0, 0, renderWidht, renderHeight));
}
}
}
精彩评论