Google WindowsPhone: Image crop with rectangle ,Beginners Tutorials (C#-XAML) | SubramanyamRaju Xamarin & Windows App Dev Tutorials

Wednesday, 26 November 2014

WindowsPhone: Image crop with rectangle ,Beginners Tutorials (C#-XAML)

Introduction:

Especially for photo apps,we may need to crop the image with rectangle which is little bit difficult to implement through the code.However i will explained very clearly in this post with help of WriteableBitmap .

Requirements:

This sample is targeted to windowsphone 7.1 OS

Description:

In this sample i was cropped the image with rectangle,and then saved it to 'MedialLibrary'.So lets start the development by following steps.
Step 1:
  • Open Visual Studio
  • Create new project name(Ex: "ImageCropWithRect")
Step 2:
Open MainPage.xaml and add following xaml code.
XAML

<Grid x:Name="LayoutRoot" Background="White"        <Grid.RowDefinitions            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="*"/> 
        </Grid.RowDefinitions> 
        <!--ContentPanel - place additional content here--> 
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> 
        <StackPanel Orientation="Vertical"            <TextBlock HorizontalAlignment="Center" FontSize="30" Text="Image Crop with Recatngle" Foreground="#FF17CDC4"/> 
            <Rectangle Margin="0,5,0,0" Height="0.5" Fill="#FF17CDC4" /> 
            <Canvas Height="300" Margin="5" x:Name="canvas" Width="480"                <!--Original Image--> 
                <Image Width="470" Stretch="Uniform" Name="OriginalImage" Source="/Assets/Nature1.jpg" MouseLeftButtonDown="OriginalImage_MouseLeftButtonDown" MouseLeftButtonUp="OriginalImage_MouseLeftButtonUp" MouseMove="OriginalImage_MouseMove"/> 
                <!--Rectangle to be used for Crop Original Image--> 
                <Rectangle x:Name="rect" StrokeThickness="4" Stroke="#FFEA18A7"></Rectangle> 
            </Canvas> 
            <Button Name="CropBtn" Content="CropImage" Background="#FF3CD3CC" Click="CropBtn_Click" /> 
            <!--Cropped Image--> 
            <Image Stretch="None" Name="FinalCroppedImage"/> 
            <Button Name="SaveBtn" Visibility="Collapsed" Content="Save to Gallery" Background="#FF3CD3CC" Click="SaveBtn_Click" /> 
        </StackPanel> 
    </Grid>
In above code In Canvas layout I added two child controls(OriginalImage,rect).Here 'rect' is used for crop the 'OriginalImage' with rectangle shape.So when click the 'CropBtn' ,selected rectangle area of OriginalImage source will be set to 'FinalCroppedImage'.And cropped image will be saved to media library when you click on 'SaveBtn' .However you will be understand the above code by moving to further important steps.
Step 2:
To crop image ,we need to (x, y) co-ordinates and the height & width of the cropped image.On MouseEvents of 'OriginalImage' get the Poin1,Point2 values to make image crop with rectangle shape.
C#

       //Mouse Move 
        private void OriginalImage_MouseMove(object sender, MouseEventArgs e) 
        { 
            Point2 = e.GetPosition(OriginalImage); 
        } 
        //Mouse Up 
        private void OriginalImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
        { 
            Point2 = e.GetPosition(OriginalImage); 
        } 
        //Mouse Down 
        private void OriginalImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
        { 
            Point1 = e.GetPosition(OriginalImage);//Set first touchable coordinates as point1 
            Point2 = Point1; 
            rect.Visibility = Visibility.Visible;           
        }
And draw the dynamic rectangle on mouse move of 'OriginalImage'
C#

Point Point1, Point2; 
 public MainPage() 
        { 
            InitializeComponent(); 
            //fire when render frame 
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); 
         } 
private void CompositionTarget_Rendering(object sender, EventArgs e) 
        { 
            //Used for rendering the cropping rectangle on the image. 
            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); 
        }

Step 3:

Make sure to set 'WriteableBitmap' with OrgianlImage on PageLoad.

C#

WriteableBitmap WB_CapturedImage;//for original image 
WriteableBitmap WB_CroppedImage;//for cropped image 
public MainPage() 
        { 
            InitializeComponent(); 
            //fire when render frame 
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering); 
            this.Loaded+=MainPage_Loaded; 
        } 
        private void MainPage_Loaded(object sender, RoutedEventArgs e) 
        { 
            //Set WriteableBitmap with OrgianlImage 
            WB_CapturedImage = new WriteableBitmap(OriginalImage, null); 
        }

Step 4:

Get the cropped image area when click on 'CropBtn' and set it to 'FinalCroppedImage'.


C#

private void CropBtn_Click(object sender, RoutedEventArgs e) 
        { 
            // Get the size of the source image 
            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 = OriginalImage.ActualWidth; 
            double displayedHeight = OriginalImage.ActualHeight; 
 
            // Calculate the ratio of the original image to the displayed image 
            double widthRatio = originalImageWidth / displayedWidth; 
            double heightRatio = originalImageHeight / displayedHeight; 
 
            // Create a new WriteableBitmap. The size of the bitmap is the size of the cropping rectangle 
            // drawn by the user, multiplied by the image size ratio. 
            WB_CroppedImage = new WriteableBitmap((int)(widthRatio * Math.Abs(Point2.X - Point1.X)), (int)(heightRatio * Math.Abs(Point2.Y - Point1.Y))); 
 
            // Calculate the offset of the cropped image. This is the distance, in pixels, to the top left corner 
            // of the cropping rectangle, multiplied by the image size ratio. 
            int xoffset = (int)(((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio); 
            int yoffset = (int)(((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio); 
 
            // Copy the pixels from the targeted region of the source image into the target image,  
            // using the calculated offset 
            if (WB_CroppedImage.Pixels.Length > 0) 
            { 
                for (int i = 0; i < WB_CroppedImage.Pixels.Length; i++) 
                { 
                    int x = (int)((i % WB_CroppedImage.PixelWidth) + xoffset); 
                    int y = (int)((i / WB_CroppedImage.PixelWidth) + yoffset); 
                    WB_CroppedImage.Pixels[i] = WB_CapturedImage.Pixels[y * WB_CapturedImage.PixelWidth + x]; 
                } 
 
                // Set the source of the image control to the new cropped image 
                FinalCroppedImage.Source = WB_CroppedImage; 
                SaveBtn.Visibility = Visibility.Visible; 
                 
            } 
            else 
            { 
                FinalCroppedImage.Source = null; 
                SaveBtn.Visibility = Visibility.Collapsed; 
            } 
            //rect.Visibility = Visibility.Collapsed; 
        }

Step 5:

Finally save cropped image to MediaLibary when click on 'SaveBtn'.

C#

private void SaveBtn_Click(object sender, RoutedEventArgs e) 
        { 
            try 
            { 
                String tempJPEG = "CroppedImage.jpg"; 
                //Create virtual store and file stream. Check for duplicate tempJPEG files. 
                var myStore = IsolatedStorageFile.GetUserStoreForApplication(); 
                if (myStore.FileExists(tempJPEG)) 
                { 
                    myStore.DeleteFile(tempJPEG); 
                } 
                IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG); 
                //Encode the WriteableBitmap into JPEG stream and place into isolated storage. 
                Extensions.SaveJpeg(WB_CroppedImage, myFileStream, WB_CroppedImage.PixelWidth, WB_CroppedImage.PixelHeight, 085); 
                myFileStream.Close(); 
                //Create a new file stream. 
                myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read); 
 
                //Add the JPEG file to the photos library on the device. 
                MediaLibrary library = new MediaLibrary(); 
                Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream); 
                MessageBox.Show("Cropped image saved successfully to media library!"); 
                myFileStream.Close(); 
            } 
            catch 
            { 
                MessageBox.Show("Error on image saving!"); 
            } 
        }

Note:

1)You need to add a reference to the Microsoft.Xna.Framework in the references of your project.

2)Make sure you have the ID_CAP_MEDIALIB turned on in your WMAppManifest.xml file.

Result:



ImageCrop

FeedBack Note:
Please share your thoughts,what you think about this post,Is this post really helpful for you?I always welcome if you drop comments on this post and it would be impressive.

Follow me always at  
Have a nice day by  :)


5 comments:

  1. nice..and great..
    but can you show some example..crop an image with perspektif correction and interpolation with C#...
    im very2 gracaeful for your concern...

    ReplyDelete
  2. can you please tell me how to drag the rectangle for above example. Suppose i selected some part for editing. now i want to drag that rectangle. how to do this?

    ReplyDelete
  3. Windows Phone 8.1? Don't you just hate Microsoft? You go and learn all this hard stuff and then they go and screw it up and change it all. Damn them!

    ReplyDelete
  4. Hi I am working on windows phone 8.1 in this Mouseup, mousedown events not there in windows 8.1 can you help how it will work windows phone 8.1

    ReplyDelete

Search Engine Submission - AddMe