ImageCropper Control可讓使用者自由裁剪影像。
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Page x:Class="ImageCropperExperiment.Samples.ImageCropperSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ImageCropperExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid RowSpacing="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:ImageCropper x:Name="imageCropper"
Width="520"
Height="520"
AspectRatio="{x:Bind local:ImageCropperSample.ConvertStringToAspectRatio(AspectRatioSetting), Mode=OneWay}"
CropShape="{x:Bind local:ImageCropperSample.ConvertStringToCropShape(CropShapeSetting), Mode=OneWay}"
ThumbPlacement="{x:Bind local:ImageCropperSample.ConvertStringToThumbPlacement(ThumbPlacementSetting), Mode=OneWay}" />
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
Orientation="Horizontal"
Spacing="8">
<Button Click="PickButton_Click"
Content="Pick image"
Style="{StaticResource AccentButtonStyle}" />
<Button Click="SaveButton_Click"
Content="Save"
Style="{StaticResource AccentButtonStyle}" />
<Button Click="ResetButton_Click"
Content="Reset"
Style="{StaticResource AccentButtonStyle}" />
</StackPanel>
</Grid>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.WinUI.Controls;
using Windows.Storage;
using Windows.Storage.Pickers;
namespace ImageCropperExperiment.Samples;
[ToolkitSampleMultiChoiceOption("ThumbPlacementSetting", "All", "Corners", Title = "Thumb Placement")]
[ToolkitSampleMultiChoiceOption("CropShapeSetting", "Rectangular", "Circular", Title = "Crop Shape")]
[ToolkitSampleMultiChoiceOption("AspectRatioSetting", "Custom", "Square", "Landscape(16:9)", "Portrait(9:16)", "4:3", "3:2", Title = "Aspect Ratio")]
[ToolkitSample(id: nameof(ImageCropperSample), "ImageCropper", description: $"A sample for showing how to create and use a {nameof(ImageCropper)}.")]
public sealed partial class ImageCropperSample : Page
{
public ImageCropperSample()
{
this.InitializeComponent();
_ = Load();
}
private async Task Load()
{
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Owl.jpg"));
await imageCropper.LoadImageFromFile(file);
}
private async Task PickImage()
{
var filePicker = new FileOpenPicker
{
ViewMode = PickerViewMode.Thumbnail,
SuggestedStartLocation = PickerLocationId.PicturesLibrary,
FileTypeFilter =
{
".png", ".jpg", ".jpeg"
}
};
var file = await filePicker.PickSingleFileAsync();
if (file != null && imageCropper != null)
{
await imageCropper.LoadImageFromFile(file);
}
}
private async Task SaveCroppedImage()
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.PicturesLibrary,
SuggestedFileName = "Cropped_Image",
FileTypeChoices =
{
{ "PNG Picture", new List<string> { ".png" } },
{ "JPEG Picture", new List<string> { ".jpg" } }
}
};
var imageFile = await savePicker.PickSaveFileAsync();
if (imageFile != null)
{
BitmapFileFormat bitmapFileFormat;
switch (imageFile.FileType.ToLower())
{
case ".png":
bitmapFileFormat = BitmapFileFormat.Png;
break;
case ".jpg":
bitmapFileFormat = BitmapFileFormat.Jpeg;
break;
default:
bitmapFileFormat = BitmapFileFormat.Png;
break;
}
using (var fileStream = await imageFile.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
await imageCropper.SaveAsync(fileStream, bitmapFileFormat);
}
}
}
public static ThumbPlacement ConvertStringToThumbPlacement(string placement) => placement switch
{
"All" => ThumbPlacement.All,
"Corners" => ThumbPlacement.Corners,
_ => throw new System.NotImplementedException(),
};
public static CropShape ConvertStringToCropShape(string cropshape) => cropshape switch
{
"Circular" => CropShape.Circular,
"Rectangular" => CropShape.Rectangular,
_ => throw new System.NotImplementedException(),
};
public static double? ConvertStringToAspectRatio(string ratio) => ratio switch
{
"Custom" => null,
"Square" => 1,
"Landscape(16:9)" => 16d / 9d,
"Portrait(9:16)" => 9d / 16d,
"4:3" => 4d / 3d,
"3:2" => 3d / 2d,
_ => throw new System.NotImplementedException(),
};
private async void PickButton_Click(object sender, RoutedEventArgs e)
{
await PickImage();
}
private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
await SaveCroppedImage();
}
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
imageCropper.Reset();
}
}
語法
<Page ...
xmlns:controls="using:CommunityToolkit.WinUI.Controls"/>
<controls:ImageCropper x:Name="ImageCropper" />
</Page>
基本使用方式
您可以使用 LoadImageFromFile(StorageFile) 方法,或設定 Source 屬性,來設定裁剪後影像的來源。
//Load an image.
await ImageCropper.LoadImageFromFile(file);
//Another way to load an image.
ImageCropper.Source = writeableBitmap;
//Saves the cropped image to a stream.
using (var fileStream = await someFile.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
await _imageCropper.SaveAsync(fileStream, BitmapFileFormat.Png);
}
使用圓形影像裁切工具
您可以將 CropShape 屬性設為以使用圓形 ImageCropper。
ImageCropper.CropShape = CropShape.Circular;
變更長寬比
您可以設定 AspectRatio 屬性來變更裁剪影像的外觀比例。
ImageCropper.AspectRatio = 16d / 9d;
或者,您也可以不受長寬比限制地裁剪圖片。
ImageCropper.AspectRatio = null;
使用覆蓋層
可使用筆刷覆蓋裁剪區域。 我們在這裡使用 RadialGradientBrush,但您可以使用任何筆刷;背景媒體筆刷、幾何筆刷、位圖和影像筆刷等等。
<Page x:Class="ImageCropperExperiment.Samples.ImageCropperOverlaySample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:local="using:ImageCropperExperiment.Samples"
xmlns:media="using:Microsoft.UI.Xaml.Media">
<Grid>
<controls:ImageCropper x:Name="ImageCropper"
Width="520"
Height="520"
AspectRatio="{x:Bind local:ImageCropperSample.ConvertStringToAspectRatio(AspectRatioSetting), Mode=OneWay}"
CropShape="{x:Bind local:ImageCropperSample.ConvertStringToCropShape(CropShapeSetting), Mode=OneWay}"
ThumbPlacement="{x:Bind local:ImageCropperSample.ConvertStringToThumbPlacement(ThumbPlacementSetting), Mode=OneWay}">
<controls:ImageCropper.Overlay>
<media:RadialGradientBrush>
<GradientStop Offset="0.75" Color="Transparent" />
<GradientStop Offset="1" Color="DimGray" />
</media:RadialGradientBrush>
</controls:ImageCropper.Overlay>
</controls:ImageCropper>
</Grid>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Windows.Storage;
namespace ImageCropperExperiment.Samples;
[ToolkitSampleMultiChoiceOption("ThumbPlacementSetting", "All", "Corners", Title = "Thumb Placement")]
[ToolkitSampleMultiChoiceOption("CropShapeSetting", "Circular", "Rectangular", Title = "Crop Shape")]
[ToolkitSampleMultiChoiceOption("AspectRatioSetting", "Custom", "Square", "Landscape(16:9)", "Portrait(9:16)", "4:3", "3:2", Title = "Aspect Ratio")]
[ToolkitSample(id: nameof(ImageCropperOverlaySample), "ImageCropper Overlay", description: $"A sample for showing how to use the overlay feature of {nameof(ImageCropper)}.")]
public sealed partial class ImageCropperOverlaySample : Page
{
public ImageCropperOverlaySample()
{
this.InitializeComponent();
_ = Load();
}
private async Task Load()
{
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Owl.jpg"));
await ImageCropper.LoadImageFromFile(file);
}
}