[英]Windows phone 8.1 crop rectangle
I m making windows phone 8.1 app which have crop function. 我正在制作具有裁剪功能的Windows Phone 8.1应用。 The problem is that i don't know how to make a graphical rectangle that user can resize and than crop image. 问题是我不知道如何制作用户可以调整大小的图形矩形,而不是裁剪图像。 Image is located on : 图片位于:
Image x:Name="ImagePreview" HorizontalAlignment="Left" Height="492" Margin="10,10,0,0" Stretch="UniformToFill" VerticalAlignment="Top" Width="380" >
Microsoft have published a sample Windows 10 application which offer crop capabilities on images. 微软已经发布了示例Windows 10应用程序,该应用程序在图像上提供了裁剪功能。 Most of the code can be reused in Windows Phone 8.1. 大多数代码可以在Windows Phone 8.1中重用。
The control is here: 控件在这里:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Controls/CropControl.cs https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Controls/CropControl.cs
And it is used in the following page: 在以下页面中使用:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Views/CropPage.xaml https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Views/CropPage.xaml
You also have to check the template declared in (search for controls:CropControl): 您还必须检查在(搜索控件:CropControl)中声明的模板:
https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Styles/Styles.xaml https://github.com/Microsoft/Appsample-Photosharing/blob/master/PhotoSharingApp/PhotoSharingApp.Universal/Styles/Styles.xaml
Here is the xaml for croping image(including croping rectangle) 这是用于裁剪图像的xaml(包括裁剪矩形)
<Grid >
<ScrollViewer>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Button Content="Pick a image" Click="Button_Click" />
<Canvas Grid.Row="1" Width="380" Height="492" Margin="10,10,0,0" VerticalAlignment="Top">
<Image x:Name="original" ImageOpened="original_ImageOpened" Stretch="Uniform" ManipulationCompleted="Rectangle_ManipulationCompleted" ManipulationDelta="Rectangle_ManipulationDelta" ManipulationStarted="Rectangle_ManipulationStarted" ManipulationMode="All" PointerPressed="rect_PointerPressed" Source="Assets/new_arrivals.png" HorizontalAlignment="Left" Height="492" Width="380" >
</Image>
<Rectangle x:Name="rect" StrokeThickness="1" Stroke="Red">
</Rectangle>
</Canvas>
<Button Grid.Row="2" Name="CropBtn" Content="CropImage" Click="CropBtn_Click" />
<Image Grid.Row="3" Stretch="None" Name="FinalCroppedImage"/>
</Grid>
</ScrollViewer>
</Grid>
code behind 背后的代码
public sealed partial class MainPage : Page
{
bool pointerpressed = false;
WriteableBitmap WB_CapturedImage;//for original image
WriteableBitmap WB_CroppedImage;//for cropped image
Point Point1, Point2;
public MainPage()
{
this.InitializeComponent();
// view = CoreApplication.GetCurrentView();
this.NavigationCacheMode = NavigationCacheMode.Required;
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
void CompositionTarget_Rendering(object sender, object 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);
}
//To generate croping rectangle
private void Rectangle_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
Point1 = e.Position;//Set first touchable cordinates as point1
Point2 = Point1;
}
private void Rectangle_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
var point = Point2;
if (e.Position.X <= original.ActualWidth && e.Position.X >= 0)
point.X = e.Position.X;
if (e.Position.Y <= original.ActualHeight && e.Position.Y >= 0)
point.Y = e.Position.Y;
Point2 = point;
}
private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var point = Point2;
// Debug.WriteLine(e.Position.X + "&&&" + original.ActualWidth);
if (e.Position.X <= original.ActualWidth && e.Position.X>=0)
point.X = e.Position.X;
if (e.Position.Y <= original.ActualHeight && e.Position.Y >= 0)
point.Y = e.Position.Y;
Point2 = point;
}
private void rect_PointerPressed(object sender, PointerRoutedEventArgs e)
{
pointerpressed = true;
Point1 = e.GetCurrentPoint(original).Position;//Set first touchable cordinates as point1
Point2 = Point1;
}
private async void CropBtn_Click(object sender, RoutedEventArgs e)
{
BitmapDecoder decoder = null;
BitmapImage bImage = original.Source as BitmapImage;
if (storageFile == null && bImage.UriSource!=null)
{
storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx://"+bImage.UriSource.AbsolutePath));
}
using (IRandomAccessStream streamWithContent = await storageFile.OpenAsync(FileAccessMode.Read))
{
decoder = await BitmapDecoder.CreateAsync(streamWithContent);
BitmapFrame bitmapFrame = await decoder.GetFrameAsync(0);
WB_CapturedImage = new WriteableBitmap((int)bitmapFrame.PixelWidth,
(int)bitmapFrame.PixelHeight);
Size cropsize = new Size(Math.Abs(Point2.X - Point1.X), Math.Abs(Point2.Y - Point1.Y));
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 = original.ActualWidth;
double displayedHeight = original.ActualHeight;
// Calculate the ratio of the original image to the displayed image
double widthRatio = originalImageWidth / displayedWidth;
double heightRatio = originalImageHeight / displayedHeight;
WB_CroppedImage = await GetCroppedBitmapAsync(streamWithContent, Point1, cropsize, widthRatio, heightRatio);
FinalCroppedImage.Source = WB_CroppedImage;
}
}
public static async Task<WriteableBitmap> GetCroppedBitmapAsync(IRandomAccessStream originalImage,
Point startPoint, Size cropSize, double scaleWidth, double scaleheight)
{
if (double.IsNaN(scaleWidth) || double.IsInfinity(scaleWidth))
{
scaleWidth = 1;
}
if (double.IsNaN(scaleheight) || double.IsInfinity(scaleheight))
{
scaleheight = 1;
}
// Convert start point and size to integer.
var startPointX = (uint)Math.Floor(startPoint.X * scaleWidth);
var startPointY = (uint)Math.Floor(startPoint.Y * scaleheight);
var height = (uint)Math.Floor(cropSize.Height * scaleheight);
var width = (uint)Math.Floor(cropSize.Width * scaleWidth);
// Create a decoder from the stream. With the decoder, we can get
// the properties of the image.
var decoder = await BitmapDecoder.CreateAsync(originalImage);
// The scaledSize of original image.
var scaledWidth = (uint)(decoder.PixelWidth);
var scaledHeight = (uint)(decoder.PixelHeight);
// Refine the start point and the size.
if (startPointX + width > scaledWidth)
{
startPointX = scaledWidth - width;
}
if (startPointY + height > scaledHeight)
{
startPointY = scaledHeight - height;
}
// Get the cropped pixels.
var pixels = await GetPixelData(decoder, startPointX, startPointY, width, height,
scaledWidth, scaledHeight);
// Stream the bytes into a WriteableBitmap
var cropBmp = new WriteableBitmap((int)width, (int)height);
var pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, (int)(width * height * 4));
return cropBmp;
}
private static async Task<byte[]> GetPixelData(BitmapDecoder decoder, uint startPointX, uint startPointY,
uint width, uint height, uint scaledWidth, uint scaledHeight)
{
var transform = new BitmapTransform();
var bounds = new BitmapBounds();
bounds.X = startPointX;
bounds.Y = startPointY;
bounds.Height = height;
bounds.Width = width;
transform.Bounds = bounds;
transform.ScaledWidth = scaledWidth;
transform.ScaledHeight = scaledHeight;
// Get the cropped pixels within the bounds of transform.
var pix = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
transform,
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.ColorManageToSRgb);
var pixels = pix.DetachPixelData();
return pixels;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.