1

我有以下自定义UserControl代表我的应用程序中的卡片:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:Core="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Namespace="clr-namespace:MyApp" xmlns:Properties="clr-namespace:MyApp.Properties" Core:Class="MyApp.Card" Height="176" RenderTransformOrigin="0.5,0.5" Width="83" UseLayoutRounding="True">
    <UserControl.LayoutTransform>
        <TransformGroup>
            <RotateTransform/>
            <ScaleTransform/>
        </TransformGroup>
    </UserControl.LayoutTransform>
    <UserControl.RenderTransform>
        <TransformGroup>
            <RotateTransform/>
            <ScaleTransform/>
        </TransformGroup>
    </UserControl.RenderTransform>
    <UserControl.Resources>
        <Namespace:ImagesConverter Core:Key="ImagesConverter"/>
    </UserControl.Resources>
    <Canvas Core:Name="Layout">
        <Image Core:Name="Image" HorizontalAlignment="Left" Source="{Binding Source={Core:Static Properties:Resources.Cards}, Converter={StaticResource ImagesConverter}}" Stretch="None" VerticalAlignment="Top">
            <Image.Clip>
                <RectangleGeometry Core:Name="Clipping" Rect="0,0,83,176"/>
            </Image.Clip>
            <Image.RenderTransform>
                <TranslateTransform Core:Name="Translation" X="0" Y="0"/>
            </Image.RenderTransform>
        </Image>
        <Rectangle Core:Name="Highlight" Canvas.Left="-2" Canvas.Top="-2" Height="180" Opacity="0.7" Stroke="#FFFFF500" StrokeThickness="3" Visibility="Collapsed" Width="87"/>
    </Canvas>
</UserControl>

正如你所看到的......我有一个包含所有卡片面的位 PNG 图像,然后,当我在构造函数中创建一个新的卡片传递SuitRank枚举值时,我计算了正确的裁剪矩形和图像的平移。一切都像一个魅力......除了当我尝试用Storyboard需要 90° 旋转的卡片为卡片设置动画时。这是我的代码(在Storyboard中定义MainWindow.Resources):

<DoubleAnimation BeginTime="00:00:00.4" Duration="00:00:00.2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" To="90"/>

结果如下:

在此处输入图像描述

在此处输入图像描述

我不明白发生了什么……但是图像会以某种方式被拉伸并且变得非常模糊,正如您所看到的。我尝试UseLayoutRounding="True"在我的卡控制以及SnapsToDevicePixels="True"MainWindow在其他地方的建议中使用......但它不起作用!当然......如果我使用LayoutTransform而不是RenderTransform一切正常旋转卡片并且卡片不模糊......但我不能让卡片围绕它的中心旋转,我的动画需要从中心旋转 90°。在我看来,为卡片高度的一半加上布局旋转动画Canvas.Top是一个非常糟糕的解决方案......而且它也让我的动画看起来很糟糕。你能建议我一个解决方案吗?

[编辑] 我尝试使用RenderOptions.BitmapScalingMode="NearestNeighbor"and RenderOptions.EdgeMode="Aliased"...但它变得更糟:

在此处输入图像描述

4

4 回答 4

3

问题在于底层图像以及布局的宽度(83)是奇数。RenderTransformOrigin,即使设置为“0.5,0.5”,也可能会向上或向下舍入该值,从而导致非常糟糕的渲染。将图像和布局宽度更改为偶数(82),完全解决了问题。

于 2013-02-18T13:16:38.770 回答
1

您可以尝试更改RenderOptionson theImage并查看是否可以找到有效的设置,我已经添加了我在应用程序中用于这种确切情况的设置示例

   RenderOptions.BitmapScalingMode="NearestNeighbor"
   RenderOptions.EdgeMode="Aliased"

例子:

    <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
           RenderOptions.EdgeMode="Aliased"
           Core:Name="Image" HorizontalAlignment="Left" Source="{Binding Source={Core:Static Properties:Resources.Cards}, Converter={StaticResource ImagesConverter}}" Stretch="None" VerticalAlignment="Top">
        <Image.Clip>
            <RectangleGeometry Core:Name="Clipping" Rect="0,0,83,176"/>
        </Image.Clip>
        <Image.RenderTransform>
            <TranslateTransform Core:Name="Translation" X="0" Y="0"/>
        </Image.RenderTransform>
    </Image>
于 2013-02-16T03:03:43.077 回答
1

您表示使用LayoutTransform效果很好,不会模糊图像。您是否尝试过使用它并将中心指定为旋转轴心?

就像是:

<Image ...>
  <Image.LayoutTransform>
    <RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/>
  </Image.LayoutTransform>
</Image>
于 2013-02-16T04:15:07.560 回答
1

正如@Tommaso Belluzzo 所说,这是来自 RenderTransformOrigin="0.5,0.5"
您上面的回答确实解决了我的问题。
请允许我显示我的代码如下:

System.Drawing.Bitmap bm = null;
//RotateTransform(angle) with RenderTransformOrigin="0.5,0.5" might cause blurry if the width or height is odd,
using (System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(path))
{
    int width = bitmap.Width;
    int height = bitmap.Height;
    if (0 != width % 2) width ++;
    if (0 != height % 2) height ++;
    bm = new System.Drawing.Bitmap(width, height);

    bm.SetResolution(96, 96);
    using (System.Drawing.Graphics g = System.Drawing. Graphics.FromImage(bm))
    {
        //I don't want to do anything which may modify(resize) the original image.
        g.Clear(System.Drawing.Color.White);
        g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
    }
    //bm.Save(directory+@"\tmp.bmp", ImageFormat.Bmp);

}
//.....(show bm)
于 2017-08-22T02:21:43.223 回答