Advertisemen
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")
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, 0, 85);
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:
Follow me always at @Subramanyam_B Have a nice day by Subramanyam Raju :)
Follow me always at @Subramanyam_B
Have a nice day by Subramanyam Raju :)
Advertisemen
Tidak ada komentar:
Posting Komentar