问题描述
我需要将图像裁剪为椭圆形,但我不想使用link中提到的Ellipse并用ImageBrush填充,相反,我需要将位图本身设置为圆形/椭圆形而不是矩形
有时候我想裁剪成矩形,有时是椭圆形,所以我不能使用椭圆和填充。
是否有其他解决方案?如果我可以以椭圆格式裁剪图像,那就更好了。
但是“图像中的剪辑”仅接受RectangleGeometry。
解决方法
您可以创建一个自定义UserControl,然后使用win2d CanvasControl显示图像,您可以在其中绘制所需形状的图像,并使用“ CreateLayer”功能遮盖图形形状。例如
在xaml:
<UserControl
x:Class="UWPClassLib.MyImageControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPClassLib"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:win2d="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
<win2d:CanvasControl x:Name="w2dCanvas"
Draw="w2dCanvas_Draw" />
</UserControl>
后面的代码:
public enum MaskShape
{
rectangle,circle
}
public sealed partial class MyImageControl : UserControl
{
public WriteableBitmap Bitmap
{
get { return (WriteableBitmap)GetValue(BitmapProperty); }
set { SetValue(BitmapProperty,value); }
}
public static readonly DependencyProperty BitmapProperty = DependencyProperty.Register(nameof(Bitmap),typeof(WriteableBitmap),typeof(MyImageControl),new PropertyMetadata(null,OnBitmapPropertyChanged));
private static void OnBitmapPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
var myctrl = (MyImageControl)d;
myctrl.TryCreateResource();
}
public MaskShape Shape
{
get { return (MaskShape)GetValue(ShapeProperty); }
set { SetValue(ShapeProperty,value); }
}
public static readonly DependencyProperty ShapeProperty = DependencyProperty.Register(nameof(Shape),typeof(MaskShape),new PropertyMetadata(MaskShape.circle));
private CanvasBitmap Source;
public MyImageControl()
{
this.InitializeComponent();
}
public void Invalidate()
{
w2dCanvas.Invalidate();
}
private void w2dCanvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
using (var session = args.DrawingSession)
{
session.Clear(Colors.Transparent);
if (CheckResourceCreated())
{
using (var mask = GetMaskShape())
using (var layer = session.CreateLayer(1.0f,mask))
{
session.DrawImage(Source);
}
// either you can do that or can use
// session.FillGeometry(mask,imagebrush); //and image brush can be made from source e.g.
// imagebrush = new CanvasImageBrush(w2dCanvas,Source);
}
}
}
private CanvasGeometry GetMaskShape()
{
switch (Shape)
{
default:
case MaskShape.circle:
var center = new System.Numerics.Vector2((float)this.ActualWidth / 2,(float)this.ActualHeight / 2);
var radiusX = (float)this.ActualWidth / 2;
var radiusY = (float)this.ActualHeight / 2;
return CanvasGeometry.CreateEllipse(w2dCanvas,center,radiusX,radiusY);
case MaskShape.rectangle:
return CanvasGeometry.CreateRectangle(w2dCanvas,new Rect(0,this.ActualWidth,this.ActualHeight));
}
}
private bool CheckResourceCreated()
{
if (Source == null)
{
TryCreateResource();
}
return (Source != null);
}
private void TryCreateResource()
{
try
{
if (Bitmap == null)
return;
Source = CanvasBitmap.CreateFromBytes(w2dCanvas,Bitmap.PixelBuffer.ToArray(),Bitmap.PixelWidth,Bitmap.PixelHeight,DirectXPixelFormat.B8G8R8A8UIntNormalized);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
,现在您可以在任何以矩形或圆形显示图像的地方使用它。您只需要更改MaskShape并调用invalidate 请原谅任何错误,因为我在旅途中写了它,还没有测试它。 它只是一个想法