2013-02-16 167 views
1

我有以下的定製UserControl代表我的應用程序的卡片:當的RenderTransform RotateTransform模糊圖像

<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枚舉值的新卡片,我計算了正確的剪切rectagle和圖像轉換。 一切工作就像一個魅力...除非我嘗試使用需要90°旋轉的Storyboard動畫我的卡。這裏是我的代碼(StoryboardMainWindow.Resources定義):

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

,這裏是結果:

enter image description here

enter image description here

我不明白這是怎麼回事..但是你可以看到圖像變得很模糊。我嘗試在我的卡控制中使用UseLayoutRounding="True",並在我的MainWindow中使用SnapsToDevicePixels="True",正如其他地方所建議的那樣...但它不起作用! 當然......如果我使用LayoutTransform而不是RenderTransform旋轉卡片,一切都很完美,並且卡片不是模糊的......但是我不能讓卡片圍繞它的中心旋轉,我的動畫需要旋轉90°中央。動畫Canvas.Top對卡片高度的一半和佈局旋轉看起來像一個非常unbrilliant的解決方案......這也使我的動畫看起來非常糟糕。 你能給我一個解決方案嗎?

[編輯]我試圖用RenderOptions.BitmapScalingMode="NearestNeighbor"RenderOptions.EdgeMode="Aliased" ...但它會變得更糟:

enter image description here

回答

2

的問題是,潛在的圖像,所以佈局,有一個奇數值爲寬度(83)。 RenderTransformOrigin(即使設置爲「0.5,0.5」)可能正在向上或向下取整,導致渲染效果很差。 將圖像和佈局寬度都改爲偶數值(82),完全解決了問題。

1

你可以嘗試在Image量變到質變的RenderOptions,看看是否能找到一個設置

:作品,我在我的應用程序

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> 
+0

見我的編輯...它得到比:( – 2013-02-16 03:08:58

+0

似乎之前它不爲模糊不清,只是壞qualitiy更糟的是,也許嘗試'RenderOptions.BitmapScalingMode = 「HighQuality」''SnapToDevicePixels =「True」' – 2013-02-16 03:13:14

+0

''Canvas'同樣設置UseLayoutRounding =「True」'可能會有所幫助 – 2013-02-16 03:18:53

1

您表示使用LayoutTransform可以完美地工作,而不會模糊圖像。你有沒有嘗試過使用它,並指定中心作爲旋轉的關鍵?

是這樣的:

<Image ...> 
    <Image.LayoutTransform> 
    <RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/> 
    </Image.LayoutTransform> 
</Image> 
+0

是的......似乎沒有被識別。 – 2013-02-16 10:49:00

1

As @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([email protected]"\tmp.bmp", ImageFormat.Bmp); 

} 
//.....(show bm)