旅行好きなソフトエンジニアの備忘録

プログラミングや技術関連のメモを始めました

【WPF】 Imageを拡大/平行移動させる

表示している画像をマウスのホイールを使って拡大したり、ドラッグして平行移動させたいと思ったところ、以下の回答が評価が高かったです。

stackoverflow.com

ただ、リンクの通りに実装するとTransformGroupへキャストする時にキャストエラーが出て動作させることが出来ませんでした。でもリンク先を少し変更すると動作したのでメモしておきます。

まず、xaml側はこんな感じです。

<Border Name="Border1" ClipToBounds="True">
    <Image Name="Image1" MouseWheel="Image1_MouseWheel" MouseLeftButtonDown="Image1_MouseLeftButtonDown" MouseMove="Image1_MouseMove" MouseLeftButtonUp="Image1_MouseLeftButtonUp"/>
</Border>


次に拡大するためのロジックは以下のようになります。マウスホイールを回すことで、今マウスのある位置で拡大することができます。

private void Image1_MouseWheel(object sender, MouseWheelEventArgs e)
{
    // スケールの値を変えることでホイールを動かした時の拡大率を制御できます
    const double scale = 1.2;

    var matrix = Image1.RenderTransform.Value;
    if (e.Delta > 0)
    {
        // 拡大処理
        matrix.ScaleAt(scale, scale, e.GetPosition(this).X, e.GetPosition(this).Y);
    }
    else
    {
        // 縮小処理
        matrix.ScaleAt(1.0/scale, 1.0/scale, e.GetPosition(this).X, e.GetPosition(this).Y);
    }

    Image1.RenderTransform = new MatrixTransform(matrix);
}

f:id:ni4muraano:20171021134748p:plain:w250f:id:ni4muraano:20171021134758p:plain:w250
次にドラッグして平行移動させるロジックは以下になります。これにより、左クリックを押したままドラッグすることで画像を平行移動できます。

private Point _start;

private void Image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Image1.CaptureMouse();
    _start = e.GetPosition(Border1);
}

private void Image1_MouseMove(object sender, MouseEventArgs e)
{
    if (Image1.IsMouseCaptured)
    {
        var matrix = Image1.RenderTransform.Value;

        Vector v = _start - e.GetPosition(Border1);
        matrix.Translate(-v.X, -v.Y);
        Image1.RenderTransform = new MatrixTransform(matrix);
        _start = e.GetPosition(Border1);
    }
}

private void Image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    Image1.ReleaseMouseCapture();
}

f:id:ni4muraano:20171021135234p:plain:w250f:id:ni4muraano:20171021135239p:plain:w250
最後に以下を加えるとEscキーを押した時に拡大/縮小、平行移動した画像を元に戻せます。

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Escape)
    {
        var matrix = Image1.RenderTransform.Value;
        matrix.M11 = 1.0;
        matrix.M12 = 0.0;
        matrix.M21 = 0.0;
        matrix.M22 = 1.0;
        matrix.OffsetX = 0.0;
        matrix.OffsetY = 0.0;
        Image1.RenderTransform = new MatrixTransform(matrix);
    }
}