简体   繁体   English

Windows Phone 8.1裁剪矩形

[英]Windows phone 8.1 crop rectangle

I m making windows phone 8.1 app which have crop function. 我正在制作具有裁剪功能的Windows Phone 8.1应用。 The problem is that i don't know how to make a graphical rectangle that user can resize and than crop image. 问题是我不知道如何制作用户可以调整大小的图形矩形,而不是裁剪图像。 Image is located on : 图片位于:

Image x:Name="ImagePreview" HorizontalAlignment="Left" Height="492" Margin="10,10,0,0" Stretch="UniformToFill" VerticalAlignment="Top" Width="380" >

Microsoft have published a sample Windows 10 application which offer crop capabilities on images. 微软已经发布了示例Windows 10应用程序,该应用程序在图像上提供了裁剪功能。 Most of the code can be reused in Windows Phone 8.1. 大多数代码可以在Windows Phone 8.1中重用。

The control is here: 控件在这里:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Controls/CropControl.cs https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Controls/CropControl.cs

And it is used in the following page: 在以下页面中使用:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Views/CropPage.xaml https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Views/CropPage.xaml

You also have to check the template declared in (search for controls:CropControl): 您还必须检查在(搜索控件:CropControl)中声明的模板:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Styles/Styles.xaml https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Styles/Styles.xaml

Here is the xaml for croping image(including croping rectangle) 这是用于裁剪图像的xaml(包括裁剪矩形)

<Grid >
        <ScrollViewer>
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                </Grid.RowDefinitions>
                <Button Content="Pick a image" Click="Button_Click" />
                <Canvas Grid.Row="1" Width="380" Height="492"  Margin="10,10,0,0" VerticalAlignment="Top">
                    <Image x:Name="original" ImageOpened="original_ImageOpened" Stretch="Uniform" ManipulationCompleted="Rectangle_ManipulationCompleted" ManipulationDelta="Rectangle_ManipulationDelta" ManipulationStarted="Rectangle_ManipulationStarted" ManipulationMode="All" PointerPressed="rect_PointerPressed" Source="Assets/new_arrivals.png" HorizontalAlignment="Left" Height="492" Width="380"  >

                    </Image>
                    <Rectangle x:Name="rect"  StrokeThickness="1" Stroke="Red">
                    </Rectangle>
                </Canvas>
                <Button Grid.Row="2" Name="CropBtn" Content="CropImage"  Click="CropBtn_Click" />
                <Image Grid.Row="3" Stretch="None" Name="FinalCroppedImage"/>
            </Grid>
        </ScrollViewer>
    </Grid>

code behind 背后的代码

 public sealed partial class MainPage : Page
    {
        bool pointerpressed = false;
        WriteableBitmap WB_CapturedImage;//for original image
        WriteableBitmap WB_CroppedImage;//for cropped image
        Point Point1, Point2;
        public MainPage()
        {
            this.InitializeComponent();
           // view = CoreApplication.GetCurrentView();
            this.NavigationCacheMode = NavigationCacheMode.Required;
            CompositionTarget.Rendering += CompositionTarget_Rendering;
        }

        void CompositionTarget_Rendering(object sender, object e)
        {
            rect.SetValue(Canvas.LeftProperty, (Point1.X < Point2.X) ? Point1.X : Point2.X);
            rect.SetValue(Canvas.TopProperty, (Point1.Y < Point2.Y) ? Point1.Y : Point2.Y);
            rect.Width = (int)Math.Abs(Point2.X - Point1.X);
            rect.Height = (int)Math.Abs(Point2.Y - Point1.Y);
        }
    //To generate croping rectangle
    private void Rectangle_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
            {
                Point1 = e.Position;//Set first touchable cordinates as point1
                Point2 = Point1;
            }

            private void Rectangle_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
            {
                var point = Point2;
                if (e.Position.X <= original.ActualWidth && e.Position.X >= 0)
                    point.X = e.Position.X;
                if (e.Position.Y <= original.ActualHeight && e.Position.Y >= 0)
                    point.Y = e.Position.Y;
                Point2 = point;
            }

            private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
            {
                var point = Point2;
               // Debug.WriteLine(e.Position.X + "&&&" + original.ActualWidth);
                if (e.Position.X <= original.ActualWidth && e.Position.X>=0)
                    point.X = e.Position.X;
                if (e.Position.Y <= original.ActualHeight && e.Position.Y >= 0)
                    point.Y = e.Position.Y;
                Point2 = point;
            }

            private void rect_PointerPressed(object sender, PointerRoutedEventArgs e)
            {
                pointerpressed = true;
                Point1 = e.GetCurrentPoint(original).Position;//Set first touchable cordinates as point1
                Point2 = Point1;
            }
 private async void CropBtn_Click(object sender, RoutedEventArgs e)
        {
            BitmapDecoder decoder = null;
            BitmapImage bImage = original.Source as BitmapImage;

            if (storageFile == null && bImage.UriSource!=null)
            {
                storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx://"+bImage.UriSource.AbsolutePath));
            }

            using (IRandomAccessStream streamWithContent = await storageFile.OpenAsync(FileAccessMode.Read))
            {        
                decoder = await BitmapDecoder.CreateAsync(streamWithContent);
                BitmapFrame bitmapFrame = await decoder.GetFrameAsync(0);
                WB_CapturedImage = new WriteableBitmap((int)bitmapFrame.PixelWidth,
                                                             (int)bitmapFrame.PixelHeight);
                Size cropsize = new Size(Math.Abs(Point2.X - Point1.X), Math.Abs(Point2.Y - Point1.Y));
                double originalImageWidth = WB_CapturedImage.PixelWidth;
                double originalImageHeight = WB_CapturedImage.PixelHeight;

                // Get the size of the image when it is displayed on the phone
                double displayedWidth = original.ActualWidth;
                double displayedHeight = original.ActualHeight;

                // Calculate the ratio of the original image to the displayed image
                double widthRatio = originalImageWidth / displayedWidth;
                double heightRatio = originalImageHeight / displayedHeight;
                WB_CroppedImage = await GetCroppedBitmapAsync(streamWithContent, Point1, cropsize, widthRatio, heightRatio);

                FinalCroppedImage.Source = WB_CroppedImage;
            }
        }
 public static async Task<WriteableBitmap> GetCroppedBitmapAsync(IRandomAccessStream originalImage,
       Point startPoint, Size cropSize, double scaleWidth, double scaleheight)
    {
        if (double.IsNaN(scaleWidth) || double.IsInfinity(scaleWidth))
        {
            scaleWidth = 1;
        }
        if (double.IsNaN(scaleheight) || double.IsInfinity(scaleheight))
        {
            scaleheight = 1;
        }
        // Convert start point and size to integer.
        var startPointX = (uint)Math.Floor(startPoint.X * scaleWidth);
        var startPointY = (uint)Math.Floor(startPoint.Y * scaleheight);
        var height = (uint)Math.Floor(cropSize.Height * scaleheight);
        var width = (uint)Math.Floor(cropSize.Width * scaleWidth);

        // Create a decoder from the stream. With the decoder, we can get 
        // the properties of the image.
        var decoder = await BitmapDecoder.CreateAsync(originalImage);

        // The scaledSize of original image.
        var scaledWidth = (uint)(decoder.PixelWidth);
        var scaledHeight = (uint)(decoder.PixelHeight);

        // Refine the start point and the size. 
        if (startPointX + width > scaledWidth)
        {
            startPointX = scaledWidth - width;
        }

        if (startPointY + height > scaledHeight)
        {
            startPointY = scaledHeight - height;
        }

        // Get the cropped pixels.
        var pixels = await GetPixelData(decoder, startPointX, startPointY, width, height,
            scaledWidth, scaledHeight);

        // Stream the bytes into a WriteableBitmap
        var cropBmp = new WriteableBitmap((int)width, (int)height);
        var pixStream = cropBmp.PixelBuffer.AsStream();
        pixStream.Write(pixels, 0, (int)(width * height * 4));

        return cropBmp;
    }

 private static async Task<byte[]> GetPixelData(BitmapDecoder decoder, uint startPointX, uint startPointY,
          uint width, uint height, uint scaledWidth, uint scaledHeight)
        {
            var transform = new BitmapTransform();
            var bounds = new BitmapBounds();
            bounds.X = startPointX;
            bounds.Y = startPointY;
            bounds.Height = height;
            bounds.Width = width;
            transform.Bounds = bounds;

            transform.ScaledWidth = scaledWidth;
            transform.ScaledHeight = scaledHeight;

            // Get the cropped pixels within the bounds of transform.
            var pix = await decoder.GetPixelDataAsync(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Premultiplied,
                transform,
                ExifOrientationMode.IgnoreExifOrientation,
                ColorManagementMode.ColorManageToSRgb);
            var pixels = pix.DetachPixelData();
            return pixels;
        }
}

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

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