Плавное вырезание изображения при прокрутке - PullRequest
0 голосов
/ 17 февраля 2012

Поэтому я пытаюсь добиться такого эффекта, как нативный кроппер, когда вы используете PhotoChooserTask.Если вы не знакомы, на заднем плане есть изображение с границей сверху, и изображение появляется, чтобы изменить непрозрачность при входе и выходе из границы.Следующий код работает нормально, но он не очень гладкий (обрезанное изображение немного отстает от перетаскивания).Есть ли способ ускорить отсечение или изменить положение вещей, чтобы уменьшить задержку?У меня есть следующий XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center">
    <Grid x:Name="cropContainer" Width="375" MouseLeftButtonDown="cropContainer_MouseLeftButtonDown" MouseLeftButtonUp="cropContainer_MouseLeftButtonUp" MouseMove="cropContainer_MouseMove">
        <Grid.RenderTransform>
            <TranslateTransform x:Name="cropTransform" />
        </Grid.RenderTransform>
        <Image x:Name="fullImage" Source="{Binding Image}" Opacity=".5" />
        <Image x:Name="clippedImage" Source="{Binding Image}">
            <Image.Clip>
                <RectangleGeometry Rect="0,0,375,267" />
            </Image.Clip>
        </Image>
    </Grid>
</Grid>
<Border x:Name="cropBorder" Grid.Row="1" BorderThickness="1" BorderBrush="White" Opacity="1" Height="267.90571169537624660018132366274" Width="375">
</Border>

и вот код для отслеживания и отсечения во время скольжения:

private Point _cropBorderOffset, _original, _newPosition;
private bool _moving;
private double _maxUp, _maxDown;

void Page_Loaded(object sender, RoutedEventArgs e)
{
    var transform = cropBorder.TransformToVisual(Application.Current.RootVisual);
    _cropBorderOffset = transform.Transform(new Point(0, 0));

    _maxDown = ((fullImage.ActualHeight - cropBorder.ActualHeight) / 2);
    _maxUp = -_maxDown;

    var rect = (clippedImage.Clip as RectangleGeometry).Rect;
    (clippedImage.Clip as RectangleGeometry).Rect = new Rect(rect.X, (fullImage.ActualHeight / 2) - 134, rect.Width, rect.Height);
}

private void cropContainer_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    cropContainer.CaptureMouse();
    _original = e.GetPosition(cropBorder);
    _moving = true;
}

private void cropContainer_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    cropContainer.ReleaseMouseCapture();
    _moving = false;
}

private void cropContainer_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
    _newPosition = e.GetPosition(cropBorder);

    if(_moving)
    {
        var deltaY = _newPosition.Y - _original.Y;

        var transform = fullImage.TransformToVisual(Application.Current.RootVisual);
        var fullImageOffset = transform.Transform(new Point(0, 0));

        var marginTop = deltaY;

        //Too far down
        if (marginTop > _maxDown)
        {
            marginTop = _maxDown;
        }
        //Too far up
        else if (marginTop < _maxUp)
        {
            marginTop = _maxUp;
        }

        cropTransform.Y = marginTop;

        var rect = (clippedImage.Clip as RectangleGeometry).Rect;
        (clippedImage.Clip as RectangleGeometry).Rect = new Rect(rect.X, _cropBorderOffset.Y - fullImageOffset.Y, rect.Width, rect.Height);
    }
}

1 Ответ

0 голосов
/ 17 февраля 2012

Вместо того, чтобы рисовать изображение дважды, один раз с отсечкой и один раз без нее, не могли бы вы просто нарисовать полупрозрачные прямоугольники, чтобы заблокировать стороны, и нарисовать белый контур для центра? Это должно значительно уменьшить отставание.

Затем вы можете использовать левую, верхнюю, ширину и высоту отсечения прямоугольника, как только позиция будет выбрана для фактического выполнения кадрирования в памяти.

...