1

私は夢中になっています。この問題を解決しようと一日中検索しました。データベースから画像をバインドし、ピンチしてズームします。

 <Grid x:Name="LayoutRoot">

    <ProgressBar x:Name="progressBar" Width="480" Margin="0,125,0,0" Height="10" VerticalAlignment="Top" IsIndeterminate="{Binding ShowProgressBar}" Visibility="{Binding ShowProgressBar, Converter={StaticResource BooleanToVisibilityConverter}}"></ProgressBar>

    <Image x:Name="image" CacheMode="BitmapCache" Width="480" Stretch="Uniform" VerticalAlignment="Center">
        <Image.RenderTransform>
            <CompositeTransform x:Name="transform" />
        </Image.RenderTransform>
        <toolkit:GestureService.GestureListener>
            <toolkit:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" PinchCompleted="OnPinchCompleted" DragDelta="OnDragDelta" DragStarted="OnDragStarted" DragCompleted="OnDragCompleted" />
        </toolkit:GestureService.GestureListener>
    </Image>

</Grid>



    private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        image = sender as Image;
        transform = image.RenderTransform as CompositeTransform;
        initialScale = transform.ScaleX;
    }

    private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        if (initialScale >= 1)
        {
            transform.ScaleX = initialScale * e.DistanceRatio;
            transform.ScaleY = initialScale * e.DistanceRatio;
        }
    }

    private void OnPinchCompleted(object sender, PinchGestureEventArgs e)
    {
        if ((transform.ScaleX < 1) || (transform.ScaleY < 1))
        {
            transform.ScaleX = 1;
            transform.ScaleY = 1;
            transform.TranslateX = 0;
            transform.TranslateY = -240;
        }
    }

    private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
    {
        PANEL_DRAG_HORIZONTAL = 0;
    }

    private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        if ((transform.ScaleX <= 1) || (transform.ScaleY <= 1))
        {
            if (e.Direction == System.Windows.Controls.Orientation.Horizontal)
            {
                PANEL_DRAG_HORIZONTAL += e.HorizontalChange;
            }
        }
        else
        {
            transform.TranslateX += e.HorizontalChange;
            transform.TranslateY += e.VerticalChange;
        }
    }

    private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
    {
        if (transform.TranslateX > 0)
            transform.TranslateX = 0;
        if (transform.TranslateY > -240)
            transform.TranslateY = -240;

        if ((transform.ScaleX <= 1) || (transform.ScaleY <= 1))
        {
            if (e.Direction == System.Windows.Controls.Orientation.Horizontal)
            {
                var abs = Math.Abs(PANEL_DRAG_HORIZONTAL);
                if (abs > 75)
                {
                    if (PANEL_DRAG_HORIZONTAL > 0) // MovePrevious;
                    { MessageBox.Show("prev"); }
                    else //MoveNext();
                    { MessageBox.Show("next"); }
                    e.Handled = true;
                }
            }
        }
    }

しかし、変換後に画像の正しいサイズを取得できません。これは、左/下側でドラッグした後に画像が失われるのを避けたいためです...ここで上/左のこの問題を簡単に処理しました

  private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
    {
        if (transform.TranslateX > 0)
            transform.TranslateX = 0;
        if (transform.TranslateY > -240)
            transform.TranslateY = -240;

不明な点がありましたら申し訳ありませんが、私は本当に打ちのめされています...あなたの助けを願っています

4

2 に答える 2

3

画像の元の境界 (x、y、幅、高さ) がある場合は、それらを変換して自分で実行し、結果を確認できます。

Rect newBounds = transform.TransformBounds(new Rect(imgX,imgY,imgWidth,imgHeight));
于 2013-02-26T19:07:21.710 に答える
-1

この方法で解決しました。スワップ時に画像をナビゲートするコードもあります

 // these two fields fully define the zoom state:
    private double TotalImageScale = 1d;
    private Point ImagePosition = new Point(0, 0);

    private const double MAX_IMAGE_ZOOM = 5;
    private Point _oldFinger1;
    private Point _oldFinger2;
    private double _oldScaleFactor;

    double PANEL_DRAG_HORIZONTAL = 0;

    #region Event handlers

    /// <summary>
    /// Initializes the zooming operation
    /// </summary>
    private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        _oldFinger1 = e.GetPosition(ImgZoom, 0);
        _oldFinger2 = e.GetPosition(ImgZoom, 1);
        _oldScaleFactor = 1;
    }

    /// <summary>
    /// Computes the scaling and translation to correctly zoom around your fingers.
    /// </summary>
    private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        var scaleFactor = e.DistanceRatio / _oldScaleFactor;
        if (!IsScaleValid(scaleFactor))
            return;

        var currentFinger1 = e.GetPosition(ImgZoom, 0);
        var currentFinger2 = e.GetPosition(ImgZoom, 1);

        var translationDelta = GetTranslationDelta(
            currentFinger1,
            currentFinger2,
            _oldFinger1,
            _oldFinger2,
            ImagePosition,
            scaleFactor);

        _oldFinger1 = currentFinger1;
        _oldFinger2 = currentFinger2;
        _oldScaleFactor = e.DistanceRatio;

        UpdateImageScale(scaleFactor);
        UpdateImagePosition(translationDelta);
    }

    /// <summary>
    /// Resets the image scaling and position
    /// </summary>
    private void OnDoubleTap(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
    {
        ResetImagePosition();
    }

    private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
    {
        PANEL_DRAG_HORIZONTAL = 0;
    }

    /// <summary>
    /// Moves the image around following your finger.
    /// </summary>
    private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        if (e.Direction == System.Windows.Controls.Orientation.Horizontal)
            PANEL_DRAG_HORIZONTAL += e.HorizontalChange;

        var translationDelta = new Point(e.HorizontalChange, e.VerticalChange);

        if (IsDragValid(1, translationDelta))
            UpdateImagePosition(translationDelta);
    }

    private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
    {
        if ((e.Direction == System.Windows.Controls.Orientation.Horizontal) && (TotalImageScale <= 1.1))
        {
            var abs = Math.Abs(PANEL_DRAG_HORIZONTAL);
            if (abs > 75)
            {
                if (PANEL_DRAG_HORIZONTAL > 0) // MovePrevious;
                {
                    if (pictureId > 0)
                    {
                        _MyProgressBar.ShowProgressBar = true;
                        pictureId--;
                        LoadPictures(AllPictures[pictureId]);
                    }
                    else
                        MessageBox.Show("first");
                }
                else //MoveNext();
                {
                    if (pictureId < count)
                    {
                        _MyProgressBar.ShowProgressBar = true;
                        pictureId++;
                        LoadPictures(AllPictures[pictureId]);
                    }
                    else
                        MessageBox.Show("last");
                }
                e.Handled = true;
            }
        }
    }

    #endregion

    #region Utils

    /// <summary>
    /// Computes the translation needed to keep the image centered between your fingers.
    /// </summary>
    private Point GetTranslationDelta(
        Point currentFinger1, Point currentFinger2,
        Point oldFinger1, Point oldFinger2,
        Point currentPosition, double scaleFactor)
    {
        var newPos1 = new Point(
         currentFinger1.X + (currentPosition.X - oldFinger1.X) * scaleFactor,
         currentFinger1.Y + (currentPosition.Y - oldFinger1.Y) * scaleFactor);

        var newPos2 = new Point(
         currentFinger2.X + (currentPosition.X - oldFinger2.X) * scaleFactor,
         currentFinger2.Y + (currentPosition.Y - oldFinger2.Y) * scaleFactor);

        var newPos = new Point(
            (newPos1.X + newPos2.X) / 2,
            (newPos1.Y + newPos2.Y) / 2);

        return new Point(
            newPos.X - currentPosition.X,
            newPos.Y - currentPosition.Y);
    }

    /// <summary>
    /// Updates the scaling factor by multiplying the delta.
    /// </summary>
    private void UpdateImageScale(double scaleFactor)
    {
        TotalImageScale *= scaleFactor;
        ApplyScale();
    }

    /// <summary>
    /// Applies the computed scale to the image control.
    /// </summary>
    private void ApplyScale()
    {
        ((CompositeTransform)ImgZoom.RenderTransform).ScaleX = TotalImageScale;
        ((CompositeTransform)ImgZoom.RenderTransform).ScaleY = TotalImageScale;
    }

    /// <summary>
    /// Updates the image position by applying the delta.
    /// Checks that the image does not leave empty space around its edges.
    /// </summary>
    private void UpdateImagePosition(Point delta)
    {
        var newPosition = new Point(ImagePosition.X + delta.X, ImagePosition.Y + delta.Y);

        if (newPosition.X > 0) newPosition.X = 0;
        if (newPosition.Y > 0) newPosition.Y = 0;

        if ((ImgZoom.ActualWidth * TotalImageScale) + newPosition.X < ImgZoom.ActualWidth)
            newPosition.X = ImgZoom.ActualWidth - (ImgZoom.ActualWidth * TotalImageScale);

        if ((ImgZoom.ActualHeight * TotalImageScale) + newPosition.Y < ImgZoom.ActualHeight)
            newPosition.Y = ImgZoom.ActualHeight - (ImgZoom.ActualHeight * TotalImageScale);

        ImagePosition = newPosition;

        ApplyPosition();
    }

    /// <summary>
    /// Applies the computed position to the image control.
    /// </summary>
    private void ApplyPosition()
    {
        ((CompositeTransform)ImgZoom.RenderTransform).TranslateX = ImagePosition.X;
        ((CompositeTransform)ImgZoom.RenderTransform).TranslateY = ImagePosition.Y;
    }

    /// <summary>
    /// Resets the zoom to its original scale and position
    /// </summary>
    private void ResetImagePosition()
    {
        TotalImageScale = 1;
        ImagePosition = new Point(0, 0);
        ApplyScale();
        ApplyPosition();
    }

    /// <summary>
    /// Checks that dragging by the given amount won't result in empty space around the image
    /// </summary>
    private bool IsDragValid(double scaleDelta, Point translateDelta)
    {
        if (ImagePosition.X + translateDelta.X > 0 || ImagePosition.Y + translateDelta.Y > 0)
            return false;

        if ((ImgZoom.ActualWidth * TotalImageScale * scaleDelta) + (ImagePosition.X + translateDelta.X) < ImgZoom.ActualWidth)
            return false;

        if ((ImgZoom.ActualHeight * TotalImageScale * scaleDelta) + (ImagePosition.Y + translateDelta.Y) < ImgZoom.ActualHeight)
            return false;

        return true;
    }

    /// <summary>
    /// Tells if the scaling is inside the desired range
    /// </summary>
    private bool IsScaleValid(double scaleDelta)
    {
        return (TotalImageScale * scaleDelta >= 1) && (TotalImageScale * scaleDelta <= MAX_IMAGE_ZOOM);
    }

    #endregion
于 2013-02-27T13:33:59.050 に答える