5

我有这个 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>

该xaml的结果是(正确大小)

在此处输入图像描述

如果我在上面的 xaml 中取消注释旋转变换,我会得到这个(错误的大小) 在此处输入图像描述

4

2 回答 2

3

图纸是矩形。并且旋转的矩形比未旋转的矩形具有更大的边界框,因此必须对其进行缩放以适应原始边界。

您可以通过指定最外层 DrawingGroup 的 ClipGeometry 来解决此问题 - 只需将其剪辑到原始边界即可。

<DrawingGroup.ClipGeometry>
    <RectangleGeometry Rect="0 0 240 240" />
</DrawingGroup.ClipGeometry>
于 2011-05-30T13:02:38.403 回答
0

如果我们在 xaml 中执行此操作时它不起作用,那么它可能会从代码中起作用:

xml:

<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", 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));
    }
  }
}
于 2011-05-30T13:05:01.563 回答