Introduction
Especially for photo apps, we may need to crop the image with a rectangle. That is a little bit difficult to implement using the code. However I will explain very clearly in this article using WriteableBitmap.
Requirements
This sample is targeted to the Windows Phone 7.1 OS.
Description
In this sample, I cropped the image with a rectangle and then saved it to "MedialLibrary". So let's start the development by the following procedure.
Step 1
- Open Visual Studio.
- Create a new project named for example "ImageCropWithRect".
Step 2
Open MainPage.xaml and add the following XMAL code.
XAML
- <Grid x:Name="LayoutRoot" Background="White">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
-
- <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">
-
- <Image Width="470" Stretch="Uniform" Name="OriginalImage" Source="/Assets/Nature1.jpg" MouseLeftButtonDown="OriginalImage_MouseLeftButtonDown" MouseLeftButtonUp="OriginalImage_MouseLeftButtonUp" MouseMove="OriginalImage_MouseMove"/>
-
- <Rectangle x:Name="rect" StrokeThickness="4" Stroke="#FFEA18A7"></Rectangle>
- </Canvas>
- <Button Name="CropBtn" Content="CropImage" Background="#FF3CD3CC" Click="CropBtn_Click" />
-
- <Image Stretch="None" Name="FinalCroppedImage"/>
- <Button Name="SaveBtn" Visibility="Collapsed" Content="Save to Gallery" Background="#FF3CD3CC" Click="SaveBtn_Click" />
- </StackPanel>
- </Grid>
In the code above in the Canvas layout I added two child controls (OriginalImage and rect). Here "rect" is used for cropping the "OriginalImage" with a rectangle shape. So when we click "CropBtn", the selected rectangle area of the original image source will be set to "FinalCroppedImage". And the cropped image will be saved to the media library when you click on "SaveBtn". You will be able to understand the code above by proceeding to the further important steps.
Step 3
To crop the image, we need the (x, y) co-ordinates and the height and width of the cropped image. On the MouseEvents of "OriginalImage" get the Poin1 and Point2 values to crop the image with a rectangle.
C# Code
-
- private void OriginalImage_MouseMove(object sender, MouseEventArgs e)
- {
- Point2 = e.GetPosition(OriginalImage);
- }
-
- private void OriginalImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- Point2 = e.GetPosition(OriginalImage);
- }
-
- private void OriginalImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- Point1 = e.GetPosition(OriginalImage);
- Point2 = Point1;
- rect.Visibility = Visibility.Visible;
- }
And draw the dynamic rectangle on the mouse move of "OriginalImage".
C# Code
- Point Point1, Point2;
-
- public MainPage()
- {
- InitializeComponent();
-
- CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
- }
- private void CompositionTarget_Rendering(object sender, EventArgs 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);
- }
Step 4
Be sure to set "WriteableBitmap" with the OrgianlImage on PageLoad.
C# Code
- WriteableBitmap WB_CapturedImage;
- WriteableBitmap WB_CroppedImage;
- public MainPage()
- {
- InitializeComponent();
-
- CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
- this.Loaded+=MainPage_Loaded;
- }
- private void MainPage_Loaded(object sender, RoutedEventArgs e)
- {
-
- WB_CapturedImage = new WriteableBitmap(OriginalImage, null);
- }
Step 5
Get the cropped image area when "CropBtn" is clicked and set it to "FinalCroppedImage".
C# Code
- private void CropBtn_Click(object sender, RoutedEventArgs e)
- {
-
- double originalImageWidth = WB_CapturedImage.PixelWidth;
- double originalImageHeight = WB_CapturedImage.PixelHeight;
-
-
- double displayedWidth = OriginalImage.ActualWidth;
- double displayedHeight = OriginalImage.ActualHeight;
-
-
- double widthRatio = originalImageWidth / displayedWidth;
- double heightRatio = originalImageHeight / displayedHeight;
-
-
-
- WB_CroppedImage = new WriteableBitmap((int)(widthRatio * Math.Abs(Point2.X - Point1.X)), (int)
- (heightRatio * Math.Abs(Point2.Y - Point1.Y)));
-
-
-
- int xoffset = (int)(((Point1.X < Point2.X) ? Point1.X : Point2.X) * widthRatio);
- int yoffset = (int)(((Point1.Y < Point2.Y) ? Point1.Y : Point2.X) * heightRatio);
-
-
-
- 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];
- }
-
-
- FinalCroppedImage.Source = WB_CroppedImage;
- SaveBtn.Visibility = Visibility.Visible;
-
- }
- else
- {
- FinalCroppedImage.Source = null;
- SaveBtn.Visibility = Visibility.Collapsed;
- }
-
- }
Step 6
Finally save the cropped image to the MediaLibary when we click on "SaveBtn".
C# Code
- private void SaveBtn_Click(object sender, RoutedEventArgs e)
- {
- try
- {
- String tempJPEG = "CroppedImage.jpg";
-
- var myStore = IsolatedStorageFile.GetUserStoreForApplication();
- if (myStore.FileExists(tempJPEG))
- {
- myStore.DeleteFile(tempJPEG);
- }
- IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);
-
- Extensions.SaveJpeg(WB_CroppedImage, myFileStream, WB_CroppedImage.PixelWidth, WB_CroppedImage.PixelHeight, 0, 85);
- myFileStream.Close();
-
- myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read);
-
-
- 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:
- You need to add a reference to the Microsoft.Xna.Framework in the references of your project.
- Ensure you have the ID_CAP_MEDIALIB turned on in your WMAppManifest.xml file.
Result
Summary
From this article we have learned how to crop an image with a rectangle in Windows Phone.
This article is also available at my original blog: link.