问题描述
|
我有这个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,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,240\" />
</DrawingGroup>
<ImageDrawing ImageSource=\"Images\\XPZW9.png\" Rect=\"0,240\" />
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.source>
</Image>
该xaml的结果是(正确大小)
如果我取消注释上面xaml中的旋转变换,我会得到这个(大小错误)
解决方法
图纸是矩形。旋转的矩形比不旋转的矩形具有更大的边界框,因此必须对其进行缩放以适合原始边界。
您可以通过指定最外面的DrawingGroup的ClipGeometry来解决此问题-只需将其裁剪到原始边界即可。
<DrawingGroup.ClipGeometry>
<RectangleGeometry Rect=\"0 0 240 240\" />
</DrawingGroup.ClipGeometry>
, 如果在xaml中使用它时不起作用,则可能可以通过代码运行:
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>
后台代码:
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\",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\",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,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\")),renderHeight));
ctx.Pop();// Pop the clipping
ctx.Pop();// Pop the translate
// 2nd Layer:
ctx.DrawImage(new BitmapImage(new Uri(\"pack://application:,/Images/XPZW9.png\")),renderHeight));
// 3rd Layer:
ctx.DrawImage(new BitmapImage(new Uri(\"pack://application:,/Images/zUr8D.png\")),renderHeight));
}
}
}