简体   繁体   English

在WinRT应用程序中使用矩形几何体进行裁剪

[英]Clipping Using Rectangle Geometry in WinRT application

I was previosuly using WriteableBitmapEX library for cropping images whereever my mouse moves. 我以前总是使用WriteableBitmapEX库在鼠标移动到的任何地方裁剪图像。 It seems to be a bit slow. 好像有点慢。

I want to crop the image at any random pixels and I want to asssign that cropped region to another image control . 我想在任意随机像素处裁剪图像,并希望将该裁剪区域分配给另一个图像控件。

My problem is when I am using the clip property , I am only getting the clipped region left and the whole image is going. 我的问题是,当我使用clip属性时,我只剩下被裁剪的区域,整个图像都在播放。 I want the image completely to be in the background but the cropped region should be assigned to the image control . 我希望图像完全位于背景中,但应将裁剪区域分配给图像控件。

Here's the code . 这是代码。

 private void Image1_Tapped(object sender, TappedRoutedEventArgs e)
        {
            int CropArea = 50;
            int PointShift = CropArea / 2;
            var _rect = new RectangleGeometry();
            Point pt;
            pt = e.GetPosition(Image1);

            _rect.Rect = new Rect(pt.X - PointShift, pt.Y - PointShift, 100, 100);
            Image1.Clip = _rect;
            MagnifyTip.Image1.Source=Image1.clip; //This is what I want to do . Its not happenning. 
        }


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image x:Name="Image1" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Tapped="Image1_Tapped" >
            <Image.Source >
                <BitmapImage UriSource="Assets/Jellyfish.png" />
            </Image.Source>
        </Image>
    </Grid>

Any better solutions are welcomed becuase I have to keep on moving my finger around the image and get the updated pixel by pixel cropped image in my imagebox in my user control 欢迎使用任何更好的解决方案,因为我必须继续在图像上移动手指,并在用户控件的imagebox中获取逐像素裁剪的更新图像

Well you don't want to clip the image you want in the background, you want two separate image controls and only clip the image you are magnifying, here is how I would do it using a Canvas and two image controls. 好吧,您不想剪切背景中想要的图像,想要两个单独的图像控件,而只剪切您要放大的图像,这就是我将如何使用Canvas和两个图像控件来进行剪切。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="canvas">
        <Image Canvas.ZIndex="0"  x:Name="Image1" ImageOpened="Image1_Opened" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Tapped="Image1_Tapped" >
            <Image.Source>
                <BitmapImage UriSource="Assets/JellyFish.png" />
            </Image.Source>
        </Image>
        <Image Canvas.ZIndex="1" x:Name="MagnifyTip" Visibility="Collapsed">
            <Image.Source >
                <BitmapImage UriSource="Assets/JellyFish.png" />
            </Image.Source>
        </Image>
    </Canvas>
</Grid>

Once your background image is loaded you want to set the sizes for images in the canvas. 加载背景图像后,您要设置画布中图像的大小。

    double _scaleX = 5;
    double _scaleY = 5;
    double _croppedImageWidth = 100;
    double _croppedImageHeight = 100;

    private void Image1_Opened(object sender, RoutedEventArgs e)
    {
        this.Image1.MaxHeight = this.canvas.ActualHeight;
        this.Image1.MaxWidth = this.canvas.ActualWidth;
        this.MagnifyTip.MaxHeight = this.canvas.ActualHeight;
        this.MagnifyTip.MaxWidth = this.canvas.ActualWidth;
        this.MagnifyTip.RenderTransform = new ScaleTransform() 
        { 
            ScaleX = _scaleX,
            ScaleY = _scaleY
        };
    }

Then you can set the location and scale of your magnified image in Image1_Tapped handler. 然后,您可以在Image1_Tapped处理程序中设置放大图像的位置和比例。

    private void Image1_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Point pt = e.GetPosition(this.canvas);
        this.MagnifyTip.Clip = new RectangleGeometry()
        {
            Rect = new Rect()
            {
                X = pt.X, 
                Y = pt.Y, 
                Width = _croppedImageWidth / _scaleX,
                Height = _croppedImageHeight / _scaleY
            }
        };
        Canvas.SetLeft(this.MagnifyTip, -pt.X * (_scaleX - 1));
        Canvas.SetTop(this.MagnifyTip, -pt.Y * (_scaleY - 1));

        this.MagnifyTip.Visibility = Visibility.Visible;
    }

The important points are 重要的是

  • Use Canvas Left , Top and ZIndex properties to overlay the magnified image over the background image. 使用Canvas LeftTopZIndex属性将放大的图像覆盖在背景图像上。
  • Calculate clip size and location for magnified image based off of the click point and size of your scale. 根据缩放比例的点击点和大小,计算放大图像的片段大小和位置。
  • Use ScaleTransform to magnify the image. 使用ScaleTransform放大图像。

A few things to note for cropping 裁剪注意事项

  1. Use a RectangleGeometry for the Clip property of your image (you already do that) 对图像的Clip属性使用RectangleGeometry (您已经这样做了)
  2. When adjusting the crop geometry - use its Transform property rather than creating a new geometry every time you want to recrop. 调整裁剪几何时,请使用其Transform属性,而不要在每次要重新裁剪时都创建新的几何。
  3. Updating a WriteableBitmap is fairly slow, so you might be able to do that once in a while - eg when you commit the crop rectangle, but not in real time like on each PointerMove event. 更新WriteableBitmap相当慢,因此您可以偶尔执行一次-例如,当您提交裁剪矩形时,但不是像每个PointerMove事件那样实时地进行。
  4. If you want real time updates you can either 如果您想实时更新,可以
    • Use another Image element with another RectangleGeometry Clip with a transform being a scaled version of the original transform. 将另一个Image元素与另一个RectangleGeometry Clip一起使用,并将其转换为原始转换的缩放版本。 You could also use a copy of the original transform and scale the entire Image instead. 您也可以使用原始变换的副本并缩放整个Image
    • Use DirectX to render transformed output in a SwapChainPanel . 使用DirectX在SwapChainPanel呈现转换后的输出。
  5. For the final high resolution output you can use any method since processing speed is less of a factor 对于最终的高分辨率输出,您可以使用任何方法,因为处理速度影响较小
    • You could use RenderTargetBitmap.RenderAsync() to render your cropped image at screen resolution. 您可以使用RenderTargetBitmap.RenderAsync()以屏幕分辨率渲染裁剪的图像。 You might need to wrap the clipped image in another element like a Grid . 您可能需要将裁剪的图像包装在另一个元素中,例如Grid
    • You can use WriteableBitmap to do the processing - I believe the WriteableBitmapEx project on CodePlex has methods for rotating and cropping. 您可以使用WriteableBitmap进行处理-我相信CodePlex上的WriteableBitmapEx项目具有旋转和裁剪的方法。 This is CPU based though. 不过这是基于CPU的。
    • You can use DirectX, but that could be an overkill. 您可以使用DirectX,但这可能是一个过大的选择。
    • You can use WIC with BitmapDecoder , though that has limited rotation capabilities: How to resize Image in C# WinRT/winmd? 您可以将WIC与BitmapDecoder一起使用,尽管它的旋转功能有限: 如何在C#WinRT / winmd中调整图像大小?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM