在Windows Phone 8.1 silverlight中缩放,翻译和裁剪图像

时间:2016-01-04 18:58:30

标签: c# silverlight windows-phone-8.1

我需要图像比例,翻译和裁剪的功能,就像照片选择器任务在Windows Phone 8.1中所做的那样。我无法使用照片选择器任务,因为我不会从媒体照片库中选择照片或捕获图像。为了我的目的,将从服务器保存的图片列表中选择图像。我已为此编写了一些代码,但它没有按照我的意愿工作。我正在研究它4周但很难找到完美的解决方案。这是我的代码。

这是xaml代码

<phone:PhoneApplicationPage
x:Class="TransformationLearning.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="Transformation" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
        <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>


    <Grid Grid.Row="1" Background="Yellow">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid Name="grid" 
              Grid.Row="0"  
              Height="400" 
              Width="400"
              >
            <Image x:Name="myImage" Source="/Assets/Lion.jpg" 
               Stretch="UniformToFill"
               ManipulationCompleted="CompleteManipulation"
               ManipulationDelta="DeltaManipulation"
               Loaded="ImageLoaded"
               Grid.Row="1"

               >
                <Image.RenderTransform>

                    <CompositeTransform x:Name="myComposite" 

                                    />
                </Image.RenderTransform>
            </Image>
            <Rectangle Width="200" 
                   Height="200" 
                   Name="myRectangle"
                   Margin="100 100"
                   Stroke="White"
                   StrokeThickness="3" Grid.Row="1">
            </Rectangle>
        </Grid>
        <Image Name="myCropPicture" Grid.Row="1"/>
    </Grid>
    </Grid>
    </phone:PhoneApplicationPage>

这是背后的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using TransformationLearning.Resources;
using Microsoft.Xna.Framework;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using Lumia.Imaging;
using Lumia.Imaging.Transforms;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Storage;
using System.Windows.Controls.Primitives;
using System.Runtime.InteropServices.WindowsRuntime;

namespace TransformationLearning
{
    public partial class MainPage : PhoneApplicationPage
    {
        WriteableBitmap WB_CapturedImage;//for original image 
        WriteableBitmap WB_CroppedImage;//for cropped image
        double width, height;
        WriteableBitmap wb;
        CompositeTransform transform;
        GeneralTransform gt, gt1;
        System.Windows.Point absolutePosition, absolutePosition1;

        public MainPage()
        {
            InitializeComponent();
            transform = new CompositeTransform();
        }

        private void ImageLoaded(object sender, RoutedEventArgs e)
        {
            wb = new WriteableBitmap(myImage, null);                  
            myComposite.CenterX = 150;
            myComposite.CenterY = 150;
        }

        private double BoundaryCheck(double value)
        {
            if (value < 1.0)
                return 1.0;
            else if (value > 2.0)
                return 2.0;
            else
                return value;
        }
        private void DeltaManipulation(object sender,    System.Windows.Input.ManipulationDeltaEventArgs e)
        {

            transform = myComposite;
            if (e.DeltaManipulation.Scale.X == 0.0 || e.DeltaManipulation.Scale.Y == 0.0)
            {
                myComposite.ScaleX *= 1.0;
                myComposite.ScaleY *= 1.0;
            }
            else if (e.DeltaManipulation.Scale.X > 0.0)
            {
                double value = BoundaryCheck(myComposite.ScaleX*e.DeltaManipulation.Scale.X);
                myComposite.ScaleX = myComposite.ScaleY = value;

                gt = myImage.TransformToVisual(grid);
                absolutePosition = gt.Transform(new System.Windows.Point(0, 0));
                gt1 = myRectangle.TransformToVisual(grid);
                absolutePosition1 = gt1.Transform(new System.Windows.Point(0, 0));

                if ((absolutePosition1.X <= absolutePosition.X) 
                || (absolutePosition1.Y <= absolutePosition.Y) 
                || (absolutePosition1.X + myRectangle.Width >= absolutePosition.X + wb.PixelWidth)
                || (absolutePosition1.Y + myRectangle.Height >= absolutePosition.Y + wb.PixelHeight))
                {
                    myComposite = transform;
                }

            }

            gt = myImage.TransformToVisual(grid);
            absolutePosition = gt.Transform(new System.Windows.Point(0, 0));

            gt1 = myRectangle.TransformToVisual(grid);
            absolutePosition1 = gt1.Transform(new System.Windows.Point(0, 0));

            if (e.DeltaManipulation.Translation.Y > 0.0 && (absolutePosition1.Y >= (absolutePosition.Y + e.DeltaManipulation.Translation.Y)))
            {
                myComposite.TranslateY += (e.DeltaManipulation.Translation.Y-2);

            }

            if (e.DeltaManipulation.Translation.X > 0.0 && (absolutePosition1.X >= (absolutePosition.X + e.DeltaManipulation.Translation.X)))
            {
                myComposite.TranslateX += (e.DeltaManipulation.Translation.X - 2);

            }

            if (e.DeltaManipulation.Translation.Y < 0.0 && ((absolutePosition1.Y + myRectangle.Height) <= (absolutePosition.Y + e.DeltaManipulation.Translation.Y + wb.PixelHeight)))
            {
                myComposite.TranslateY += (e.DeltaManipulation.Translation.Y + 2);

            }

            if (e.DeltaManipulation.Translation.X < 0.0 && ((absolutePosition1.X + myRectangle.Width) <= (absolutePosition.X + e.DeltaManipulation.Translation.X + wb.PixelWidth)))
            {
                myComposite.TranslateX += (e.DeltaManipulation.Translation.X + 2);

            }

            wb = new WriteableBitmap(myImage, myComposite);

            gt = myImage.TransformToVisual(grid);
            absolutePosition = gt.Transform(new System.Windows.Point(0, 0));
        }

        private void CompleteManipulation(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        {


            App.RootFrame.RenderTransform = new CompositeTransform();
            grid.UpdateLayout();

            CropImage();
            App.RootFrame.RenderTransform = new CompositeTransform();
            grid.UpdateLayout();
        }

        private async void CropImage()
        {
            var ms = new MemoryStream();
            wb.SaveJpeg(ms, wb.PixelWidth, wb.PixelHeight, 0, 100);
            ms.Position = 0;
            gt1 = myRectangle.TransformToVisual(myImage);
            absolutePosition1 = gt1.Transform(new System.Windows.Point(0, 0));

            using (var source = new StreamImageSource(ms))
            {

                using (var filterEffect = new FilterEffect(source))
                {
                    var filter = new CropFilter(new Windows.Foundation.Rect(absolutePosition1.X, absolutePosition1.Y, myRectangle.Width, myRectangle.Height));

                    filterEffect.Filters = new IFilter[] { filter };
                    var target = new WriteableBitmap((int)(myRectangle.Width), (int)(myRectangle.Height));

                    using (var renderer = new WriteableBitmapRenderer(filterEffect, target))
                    {
                        try
                        {
                            await renderer.RenderAsync();
                        }
                        catch (Exception t)
                        {
                         System.Diagnostics.Debug.WriteLine(t.InnerException);
                            System.Diagnostics.Debug.WriteLine(t.Message);
                        }
                    }
                    myCropPicture.Source = target;
                }
            }
        }
    }
}

这里我使用了Lumia Imaging SDK裁剪滤镜来裁剪图像。 &#34; MYIMAGE&#34;是源图像和&#34; myCropPicture&#34;用于显示裁剪的图像。为了转换,我使用了复合变换。当我缩放源图像时,此代码无法相应地裁剪该图像。我非常需要帮助。

1 个答案:

答案 0 :(得分:0)

你查了这篇文章吗?它可能会派上用场 Image crop control for Silverlight or Windows Phone