3

画面上に 2 つのズームイン画像を並べてカスタム描画しています。それぞれが画面の半分を占めています。

OnPaint() をオーバーライドして、.net 3.5 (と思います) で以前に実行しました。

    //using System.Drawing

    /// <summary>
    /// Custom drawing
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit);
    }

DrawImage メソッドの説明: 「指定された Image の指定された部分を、指定された位置に指定されたサイズで描画します。」( MSDN )

.net 4.5 を使用して同じことを達成しようとしています。OnRender をオーバーライドし、DrawingContext オブジェクトを使用して描画を実行しています。基本的にこれは私のループです:

    //using System.Windows.Media;

    /// <summary>
    /// Overide the OnRender to have access to a lower level of drawing.
    /// </summary>
    /// <param name="drawingContext"></param>
    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf);
        drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf);
    }

引き伸ばされた画像を表示したい場合は問題なく動作します。私が欲しいのは、(Window_LeftHalf と Window_RightHalf で) 画像の一部を (ズームインのように) 表示することです。基本的に、graphics.DrawImage (上を参照) が行うことですが、DrawingContext オブジェクトを使用します。

MSDN を見ようとしましたが、興味深いものを引き出すことができませんでした。後で DrawingContext によって使用されるバッファーを作成する可能性がありますか? ズームインされた画像を保持する中間オブジェクトが必要であることはほぼ確実です。何か案は?

更新:マウスを使用して画像をナビゲートしているため、パフォーマンス重要です。例えば:

    /// <summary>
    /// Handles the mouse move events.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void MouseMoveEventHandler(RoutedEventArgs e)
    {
        // The size of the crop is always the same
        // but the portion of the picture different.
        crop.X += mouseDelta.X;
        crop.Y += mouseDelta.Y;
    }
4

2 に答える 2

0

編集ImageBrush.Viewbox2 :。 Viewbox はRect[0.0... 1.0] の寸法を持ち、以前は SourceRect であったものを制御できます。私はこれをテストしましたが、見事に動作します。私がしたこと:

私のウィンドウで:

    protected ImageBrush imgBrush = new ImageBrush(new ImageSource(new Uri("image.png")));
    protected Rect vBox = new Rect(0, 0, 1, 1);
    protected Point lastPosition = new Point(0, 0);

このための私のコンテナは、 imgBrush である tgtRect と呼ばれるWPF Rectangleでし。ズームとスクロールの方法は次のとおりです。Rect.Fill

    protected void tgtRect_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        // Zoom in when Delta is positive, Zoom out when negative
        double exp = -e.Delta / Math.Abs(e.Delta);
        double val = Math.Pow(1.1, exp);
        vBox.Scale(val, val);
        imgBrush.Viewbox = vBox;
    }

    void tgtRect_MouseMove(object sender, MouseEventArgs e)
    {
        Point thisPosition = e.GetPosition(tgtRect);
        if (e.RightButton == MouseButtonState.Pressed)
        {
            double w = tgtRect.ActualWidth;
            double h = tgtRect.ActualHeight;
            Vector offset = lastPosition - thisPosition;
            offset.X /= w;
            offset.Y /= h;
            vBox.Offset(offset);
            imgBrush.Viewbox = vBox;
        }
        lastPosition = thisPosition;
    }

実装の場合:

    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawRectangle(imgBrush, null, DesRect);
    }

描画する四角形ごとに個別の imgBrush を維持する必要がある可能性があります。上記のコード (OnRender オーバーライドではありません) を WPF ウィンドウで試してみましたRectangle.Fillが、これは Rectangle だけImageBrushで、パフォーマンスは非常に良好でした。問題があれば解決できると思いますが、最終的には ImageBrush が正しい実装になると思います。これは非常に興味深いプロジェクトでした!ご質問ありがとうございます。

編集終了 2

Rectオブジェクト「Window_LeftHalf」と「Window_RightHalf」を、イメージをレンダリングする実際のサイズに定義する必要があります。たとえば、200% ズームされている場合、 プロパティRect.WidthRect.Heightプロパティは元の ImageSource の 2 倍のサイズである必要があります。

編集

古い方法は次のとおりです。

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit);
}

「BitmapImage.SourceRect」の使用:

protected override void OnRender(DrawingContext drawingContext)
{
    BitmapImage_Left.SourceRect = SrcRectangleLeft;
    drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf);
    BitmapImage_Right.SourceRect = SrcRectangleRight;
    drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf);
}

マウス機能は SourceRect を変更できます。例えば:

private static void MouseMoveEventHandler(RoutedEventArgs e)
{
    // The size of the crop is always the same
    // but the portion of the picture different.
    SrcRectangleLeft = new Int32Rect(SrcRectangleLeft.X + mouseDelta.X, 
        SrcRectangleLeft.Y + mouseDelta.Y,
        SrcRectangleLeft.Width, SrcRectangleLeft.Height);
}

パフォーマンスがどのようになるかはわかりませんが、更新ごとにビットマップの一部を新しいオブジェクトにマッピングするよりも優れているはずです。

これがまったく役に立ったことを願っています。

于 2012-12-01T00:04:25.707 に答える