0
votes

I need the functionality of an image scale, translate and cropping just like what a photo chooser task do in windows phone 8.1. I can not use photo chooser task because I will not select the photo from media photo library or capture the image. For my purpose the image will be selected from a server saved picture list. I have written some code for this but it's not working as I desire. I am working on it for 4 weeks but hardly find the perfect solution. Here is my code.

This is the xaml code

<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>

and this is the code behind:

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;
                }
            }
        }
    }
}

Here I have used Lumia Imaging SDK crop filter for cropping the image. "myImage" is the source image and "myCropPicture" is used for showing the cropped image. For transformation I have used composite transform. When I scale the source image this code can not crop that image accordingly.I need the help badly.

1

1 Answers

0
votes