C# 剪切和缩放椭圆内的图像(不是椭圆本身)
我正试图找到一种方法,用一个椭圆剪辑一幅图像,这样如果我缩放图像,我就可以保持椭圆完整,但到目前为止,我没有运气 这是我的XAML:C# 剪切和缩放椭圆内的图像(不是椭圆本身),c#,xaml,windows-runtime,uwp,windows-10-universal,C#,Xaml,Windows Runtime,Uwp,Windows 10 Universal,我正试图找到一种方法,用一个椭圆剪辑一幅图像,这样如果我缩放图像,我就可以保持椭圆完整,但到目前为止,我没有运气 这是我的XAML: <Grid> <Grid.Clip> <RectangleGeometry x:Name="ClippingRectangle" Rect="0,0,200,200"/> </Grid.Clip> <Ellipse Stretch="Unifor
<Grid>
<Grid.Clip>
<RectangleGeometry x:Name="ClippingRectangle"
Rect="0,0,200,200"/>
</Grid.Clip>
<Ellipse Stretch="UniformToFill"
x:Name="ImageEllipse"
SizeChanged="ImageEllipse_OnSizeChanged">
<Ellipse.Fill>
<ImageBrush ImageSource="{x:Bind ViewModel.SomePath}>
</Ellipse.Fill>
</Ellipse>
</Grid>
然后:
<Storyboard x:Name="TestAnimation">
<DoubleAnimation Storyboard.TargetName="AvatarTransform"
Storyboard.TargetProperty="ScaleY"
To="1.2" Duration="0:0:1"/>
</Storyboard>
但它仍然不起作用。另外,使用这种方法,我无法设置RenerTransformOrigin
属性,因为我没有UIElement
可供使用,因此即使动画确实有效,图像也会向右和向下缩放,这不是预期的结果
编辑#4>>已解决-如标记为有效的答案所示,以下是我的代码:
<Ellipse Stretch="UniformToFill"
x:Name="ImageEllipse">
<Ellipse.Fill>
<ImageBrush ImageSource="/SomePath/SomeImage.jpg">
<ImageBrush.RelativeTransform>
<CompositeTransform CenterY="0.5"
CenterX="0.5"/>
</ImageBrush.RelativeTransform>
</ImageBrush>
</Ellipse.Fill>
</Ellipse>
事实证明,它也适用于
椭圆.Fill
属性,因此我不必切换到路径几何体来创建用于剪辑图像的圆。您可以将剪辑编辑为路径几何体,而不是矩形几何体,剪辑将起作用。下面是一个可以放大和缩小并保持在剪裁区域内的图像示例。玩这个直到它对你有用
<Grid Width="1000"
Height="1000">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="500"
Height="500">
<Grid.Clip>
<PathGeometry>
<PathFigure IsClosed="True"
StartPoint="0, 250">
<ArcSegment Size="1, 1"
Point="500, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
<ArcSegment Size="1, 1"
Point="0, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
</PathFigure>
</PathGeometry>
</Grid.Clip>
<Image Source="12019035.jpg"
RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.2"
ScaleY="1.2" />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>
</Grid>
我只是把一个网格放在一个网格里面,这样大小对于这个例子来说是正确的
我用路径剪裁了内部网格,使其成为一个完美的椭圆。请随意复制该片段,并根据需要使用它。您只需调整尺寸等,以匹配您自己的视图
为了在本例中放大和缩小图像,您需要设置动画或直接操作图像上的ScaleTransform Scale.X和Scale.Y属性,其中值为双精度,1为100%,1.5为150%,等等
如果你不确定如何使用路径,我可以解释一下,但有一些例子。它基本上是PathFigure对象的起点,PathFigure内每个段上的点是您希望遇到的下一个点。这里我从0,250开始,画一条弧到点500,250。然后我再画一条弧到0,250,完成椭圆。它使用这些数字,因为网格宽度/高度是500500
最酷的是,你可以画一个形状,或者用你想要的任何图案剪裁任何元素:)它可以是星星,或者其他疯狂的形状。这就是你要找的,但请享受其中的乐趣 我正在使用的动画:将这些资源放在页面中(XAML端)
这将从图像上的一个中心点开始设置图像动画,并在椭圆内剪裁。希望这有帮助:)你能给屏幕提供实际结果吗?你不能只使用ImageBrush.Transform
来转换图像吗?@AndriiKrupka我已经用请求的image@DecadeMoon我在动画中使用UI.Composition名称空间,所以我没有想到这一点。我尝试使用一个简单的双动画,但仍然没有运气(见更新的问题)提供了一些预期结果的图像。很难理解您在final中想要什么/很抱歉,但正如我在问题中所述,剪辑属性值只能是WinRT上的矩形几何体对象,因此此方法在UWPY上不起作用您是正确的。。。那真臭。我会继续挖掘,因为一定有办法。再次抱歉,这对我不起作用,看起来像ImageBrush上的动画。变换不起作用。至少,我在XAML和代码隐藏中尝试了两个故事板,但它们什么也没做。此外,使用这种方法无法设置RenderTransferMorigin,因此即使动画确实有效,图像最终也会向右缩放,而不是居中缩放。我开始认为这在UWP上是不可行的,至少在XAML上是不可行的…我发送了整个代码。如果您满意,请将其标记为已回答。当然,我会的,让我测试一下(现在是凌晨3点,比方说明天),这样我可以确认它确实回答了我的问题-不过这次看起来确实如此。伙计,你真的很敬业,谢谢!:)它工作得很好!我还可以继续使用椭圆,我使用你的故事板来制作内部图像的动画,我不必切换到PathGeometry,所以结果比预期的更好,非常感谢!哦,糟了,哈哈。我甚至没试过你的椭圆。我只是觉得这不是剪的哈哈。干得好。现在有道理了,我打自己的头,因为椭圆实际上只是那些或多或少已经内置的路径的一个形状。
<Ellipse Stretch="UniformToFill"
x:Name="ImageEllipse">
<Ellipse.Fill>
<ImageBrush ImageSource="/SomePath/SomeImage.jpg">
<ImageBrush.RelativeTransform>
<CompositeTransform CenterY="0.5"
CenterX="0.5"/>
</ImageBrush.RelativeTransform>
</ImageBrush>
</Ellipse.Fill>
</Ellipse>
<Grid Width="1000"
Height="1000">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="500"
Height="500">
<Grid.Clip>
<PathGeometry>
<PathFigure IsClosed="True"
StartPoint="0, 250">
<ArcSegment Size="1, 1"
Point="500, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
<ArcSegment Size="1, 1"
Point="0, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
</PathFigure>
</PathGeometry>
</Grid.Clip>
<Image Source="12019035.jpg"
RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.2"
ScaleY="1.2" />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>
</Grid>
<Page.Resources>
<Storyboard x:Name="StoryboardZoomIn">
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True"
Storyboard.TargetProperty="(Shape.Fill).(Brush.RelativeTransform).(CompositeTransform.ScaleX)"
Storyboard.TargetName="path">
<EasingDoubleKeyFrame KeyTime="0:0:1"
Value="1.5">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseIn" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True"
Storyboard.TargetProperty="(Shape.Fill).(Brush.RelativeTransform).(CompositeTransform.ScaleY)"
Storyboard.TargetName="path">
<EasingDoubleKeyFrame KeyTime="0:0:1"
Value="1.5">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseIn" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="StoryboardZoomOut">
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True"
Storyboard.TargetProperty="(Shape.Fill).(Brush.RelativeTransform).(CompositeTransform.ScaleX)"
Storyboard.TargetName="path">
<EasingDoubleKeyFrame KeyTime="0:0:1"
Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseIn" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True"
Storyboard.TargetProperty="(Shape.Fill).(Brush.RelativeTransform).(CompositeTransform.ScaleY)"
Storyboard.TargetName="path">
<EasingDoubleKeyFrame KeyTime="0:0:1"
Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseIn" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Grid Width="1000"
Height="1000">
<StackPanel>
<Button Content="Zoom In" Click="ButtonZoomIn_Click" />
<Button Content="Zoom Out" Click="ButtonZoomOut_Click"/>
</StackPanel>
<Canvas HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="500"
Height="500"
Grid.RowSpan="2">
<Path x:Name="path">
<Path.Fill>
<ImageBrush Stretch="Fill"
ImageSource="12019035.jpg">
<ImageBrush.RelativeTransform>
<CompositeTransform CenterY="0.5"
CenterX="0.5"
ScaleX="1.5"
ScaleY="1.5" />
</ImageBrush.RelativeTransform>
</ImageBrush>
</Path.Fill>
<Path.Data>
<PathGeometry>
<PathFigure IsClosed="True"
StartPoint="0, 250">
<ArcSegment Size="1, 1"
Point="500, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
<ArcSegment Size="1, 1"
Point="0, 250"
SweepDirection="Counterclockwise"
IsLargeArc="True" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
</Grid>
private void ButtonZoomIn_Click(object sender, RoutedEventArgs e)
=> (Resources["StoryboardZoomIn"] as Storyboard)?.Begin();
private void ButtonZoomOut_Click(object sender, RoutedEventArgs e)
=> (Resources["StoryboardZoomOut"] as Storyboard)?.Begin();