如何通过两个更改坐标旋转和调整PNG图像的大小?

时间:2012-10-26 03:51:34

标签: c# wpf image xaml system.drawing

如果有PNG图像连接两个坐标(如绳索),

coordinateA.x;
coordinateA.y;

coordinateB.x;
coordinateB.y;

两个坐标将一直在变化,因此PNG图像连接两个坐标之间需要调整大小和旋转。

任何示例代码都可以使这更容易吗?

1 个答案:

答案 0 :(得分:1)

这是我的方法:

Coordinates.cs:

public class Coordinates : DependencyObject
{
    public Coordinates(double x, double y)
    {
        X = x;
        Y = y;
    }
    public Coordinates()
    {
        X = 0;
        Y = 0;
    }
    //X Dependency Property
    public double X
    {
        get { return (double)GetValue(XProperty); }
        set { SetValue(XProperty, value); }
    }
    public static readonly DependencyProperty XProperty =
        DependencyProperty.Register("X", typeof(double), typeof(Coordinates), new UIPropertyMetadata(0d));
    //Y Dependency Property
    public double Y
    {
        get { return (double)GetValue(YProperty); }
        set { SetValue(YProperty, value); }
    }
    public static readonly DependencyProperty YProperty =
        DependencyProperty.Register("Y", typeof(double), typeof(Coordinates), new UIPropertyMetadata(0d));
}

Geometry.cs:

public class ConnectorLocationConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var start = (Coordinates)values[0];
        var end = (Coordinates)values[1];
        return new Thickness(start.X, start.Y, 0, 0);
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}
public class ConnectorAngleConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var start = (Coordinates)values[0];
        var end = (Coordinates)values[1];
        //dy/dx = tan(t) => t = arcTan(dy/dx)
        double t = Math.Atan2(
                    Math.Abs(start.Y - end.Y),
                    Math.Abs(start.X - end.X)) * 180 / Math.PI;
        if (end.X <= start.X && end.Y >= start.Y) return 180 - t;
        if (end.X >= start.X && end.Y <= start.Y) return -t;
        if (end.X <= start.X && end.Y <= start.Y) return 180 + t;
        return t;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}
public class ConnectorWidthConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var start = (Coordinates)values[0];
        var end = (Coordinates)values[1];
        //get side for states
        return Math.Abs(start.X - end.X);
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}
public class ConnectorHeightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var start = (Coordinates)values[0];
        var end = (Coordinates)values[1];
        //get side for states
        return Math.Abs(start.Y - end.Y);
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

MainWindow.xaml.cs:

    //nothing fancy here
    public MainWindow()
    {
        Start = new Coordinates();
        End = new Coordinates();
        DataContext = this;
        InitializeComponent();
    }
    //Start Dependency Property
    public Coordinates Start
    {
        get { return (Coordinates)GetValue(StartProperty); }
        set { SetValue(StartProperty, value); }
    }
    public static readonly DependencyProperty StartProperty =
        DependencyProperty.Register("Start", typeof(Coordinates), typeof(MainWindow), new UIPropertyMetadata(null));
    //End Dependency Property
    public Coordinates End
    {
        get { return (Coordinates)GetValue(EndProperty); }
        set { SetValue(EndProperty, value); }
    }
    public static readonly DependencyProperty EndProperty =
        DependencyProperty.Register("End", typeof(Coordinates), typeof(MainWindow), new UIPropertyMetadata(null));

    //--------------------------------------------------
    //Click causes the mouse position stick to Start/End
    //--------------------------------------------------
    bool flag = false;
    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        var p = e.GetPosition(this);
        if(flag) Start = new Coordinates(p.X, p.Y);
        else End = new Coordinates(p.X, p.Y);
    }

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
        flag = !flag;
    }

最后是MainWindow.xaml:

<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfTest"
        Title="MainWindow" Height="650" Width="825">
    <Window.Resources>
        <local:ConnectorLocationConverter x:Key="connectorLocationConverter"/>
        <local:ConnectorAngleConverter x:Key="connectorAngleConverter"/>
        <local:ConnectorWidthConverter x:Key="connectorWidthConverter"/>
        <local:ConnectorHeightConverter x:Key="connectorHeightConverter"/>
    </Window.Resources>
    <Canvas Background="#2000"
        MouseMove="Canvas_MouseMove" MouseDown="Canvas_MouseDown">
        <Canvas Width="0" Height="0">
            <Image Source="/WpfTest;component/im.png" Stretch="Fill">

                <Image.Margin>
                    <MultiBinding Converter="{StaticResource connectorLocationConverter}">
                        <Binding Path="Start"/>
                        <Binding Path="End"/>
                    </MultiBinding>
                </Image.Margin>

                <Image.Width>
                    <MultiBinding Converter="{StaticResource connectorWidthConverter}">
                        <Binding Path="Start"/>
                        <Binding Path="End"/>
                    </MultiBinding>
                </Image.Width>

                <Image.Height>
                    <MultiBinding Converter="{StaticResource connectorHeightConverter}">
                        <Binding Path="Start"/>
                        <Binding Path="End"/>
                    </MultiBinding>
                </Image.Height>

                <Image.RenderTransform>
                    <RotateTransform CenterX="0" CenterY="0">
                        <RotateTransform.Angle>
                            <MultiBinding Converter="{StaticResource connectorAngleConverter}">
                                <Binding Path="Start"/>
                                <Binding Path="End"/>
                            </MultiBinding>
                        </RotateTransform.Angle>
                    </RotateTransform>
                </Image.RenderTransform>

            </Image>
        </Canvas>
    </Canvas>
</Window>