2011-10-10 55 views
6

WPFビジュアル(UserControl)をビットマップにレンダリングしていますが、スケーリング/変換する前にレンダリングされた画像がUserControlのサイズであるという問題があります。だから、UserControlは200x200ピクセルで設計されたとしましょう。私がBMPにレンダリングすると、それぞれ200と200を報告するUserControlのActualWidthとActualHeighttを使用しています。問題は、UserControlがキャンバス内にあり、サイズが1200x1200に近いものに自動的にサイズ変更されます(変更されます)WPFビジュアルエレメントの拡大/縮小サイズを取得する方法

私はいくつかの読書と検索を行っています。有効なサイズを決定する方法、つまりコントロールがスクリーンに描かれているサイズを把握していない。

私はこの質問に遭遇しましたが、これは期待していましたが返されるTransformにはスケーリングデータが含まれていません。さて、それはありますが、両方とも1です。 Get element position after transform

レンダリングのスケーリングを探す場所については、どのような提案もあります。

[UPDATE]示唆したように、私は、関連するコードを含むよ:

public static Bitmap PngBitmap(this Visual visual) 
{ 
    // Get height and width 
    int width = (int)(double)visual.GetValue(
     FrameworkElement.ActualWidthProperty); 
    int height = (int)(double)visual.GetValue(
     FrameworkElement.ActualHeightProperty); 

    // Render 
    RenderTargetBitmap rtb = 
     new RenderTargetBitmap(
      width, 
      height, 
      96, 
      96, 
      PixelFormats.Default); 
    rtb.Render(visual); 

    // Encode 
    PngBitmapEncoder encoder = new PngBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(rtb)); 
    System.IO.MemoryStream stream = new System.IO.MemoryStream(); 
    encoder.Save(stream); 

    // Create Bitmap 
    Bitmap bmp = new Bitmap(stream); 
    stream.Close(); 

    return bmp; 
} 

public static BitmapSource BitmapSource(this Visual visual) 
{ 
    Bitmap bmp = visual.PngBitmap(); 
    IntPtr hBitmap = bmp.GetHbitmap(); 
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions(); 
    return Imaging.CreateBitmapSourceFromHBitmap(
         hBitmap, 
         IntPtr.Zero, 
         Int32Rect.Empty, 
         sizeOptions); 
} 

を[更新#2]は、XAMLを追加しました - それは巨大だったし、私からのため、Grid要素を除去しましたXAMLの読み込みキーボードUserControlを含むCanvasは、Grid要素の一部ではありませんでした。

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:PMD.HECAT.DashboardModule" 
    xmlns:PMD_HECAT_DashboardModule_VirtualKeyboard="clr-namespace:PMD.HECAT.DashboardModule.VirtualKeyboard" 
    xmlns:System_Windows_Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" 
    xmlns:PMD_HECAT_DashboardModule_Input="clr-namespace:PMD.HECAT.DashboardModule.Input" 
    xmlns:control="clr-namespace:PMD.HECAT.DashboardModule.Controls"  
    x:Class="PMD.HECAT.DashboardModule.CandidateElectrodeView"    
    x:Name="UserControl" 
    mc:Ignorable="d" 
    d:DesignWidth="1024" d:DesignHeight="768" Width="640" Height="360"> 
    <UserControl.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="../Themes/DashboardStyles.xaml" /> 
       <ResourceDictionary Source="../Themes/ImageButtons.xaml" /> 
       <ResourceDictionary Source="CandidateViewResources.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary>   
    </UserControl.Resources> 
    <UserControl.Triggers> 
     <EventTrigger RoutedEvent="PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.KeyboardClose" SourceName="virtualKeyboardView"> 
      <BeginStoryboard Storyboard="{StaticResource OnKeyboardClose1}"/> 
     </EventTrigger> 
    </UserControl.Triggers> 
    <Canvas Width="100" HorizontalAlignment="Left"> 

     <PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView x:Name="virtualKeyboardView" Height="222" Width="550" RenderTransformOrigin="0.5,0.5" Opacity="0" Active="False"> 
      <PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.RenderTransform> 
       <TransformGroup> 
        <ScaleTransform/> 
        <SkewTransform/> 
        <RotateTransform/> 
        <TranslateTransform X="40" Y="400"/> 
       </TransformGroup> 
      </PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.RenderTransform> 
     </PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView> 
     <Rectangle Stroke="White" Opacity="0.7" Fill="White" Height="370" Width="654.851" Canvas.Left="687" Canvas.Top="0" /> 
    </Canvas> 
</UserControl> 
+0

コントロールにはどのような変換が適用されますか? LayoutTransformまたは/およびRenderTransform? 「オートサイズ」とはどういう意味ですか? –

+0

@Erno - 正直なところ私は完全にはわかりません。私は新しいです、私はWPFの新しさとレイアウトツールの把握がまだありません。 UserControlは、幅と高さが伸びるように設定されたキャンバス内にあるように見えます。 –

+0

は、私たちが助けることができるようにコードを示しています。 –

答えて

5

質問がされましたが、それはいくつかの詳細情報を投稿する傷つけることはありませんので、:)

適用して、私はビジュアルの大きさ(スケール)を見つけるために、このコードを使用し、私は多くの時間が経過し知っているがs(変換レンダリング)。

GeneralTransform t = transformedVisual.TransformToVisual(parentVisual); 

Vector topLeft = (Vector) t.Transform(new Point(0,0)); 
Vector topRight = (Vector) t.Transform(new Point(originalWidthOfTransformedVisual, 0)); 

double renderedWidth = (topRight-topLeft).Length; 
double widthScale = renderedWidth/originalWidthOfTransformedVisual; 
+3

より一般的には、親に対する視覚の境界を単純に計算できます: 'Rect bounds = tもちろん、これが動作するためには、 'transformedVisual'は単純な' Visual'( '後者')ではなく 'FrameworkElement'である必要があります。それ自体には次元情報はない)。 –

0

あなたは、ビジュアルの幅と高さを使用するとします。 まず、2つの問題があります。 ビジュアル、http://msdn.microsoft.com/en-us/library/system.windows.media.visual.aspxには高さと幅のプロパティがありません。

高さと幅のプロパティを持つFrameworkElementがあると仮定して、高さと幅のプロパティまたはActualHeightとActualWidthプロパティを使用していますか? そうでない場合、それらはあなたが探しているプロパティです。

これらを使用している場合、またはFrameworkElementを使用していない場合は、コードを投稿する必要があります。

+0

混乱して申し訳ありません。実際にはUserControlで、ActualWidthとActualHeightを使用しています(これを明確にするために元のメッセージを更新しました)。 –

0

アニメーションを使用してTransformを実行することができた場合、アニメーションはCompletedイベントを提供します。新しい変換されたサイズを抽出するのに適しているはずです。

0
public static Rect GetRelativePlacement(this UIElement element, UIElement relativeTo) 
    { 
     var absolutePos = element.PointToScreen(new Point(0, 0)); 
     var posRelativeTo = relativeTo.PointToScreen(new Point(0, 0)); 

     var topLeft = new Point(absolutePos.X - posRelativeTo.X, absolutePos.Y - posRelativeTo.Y); 
     var bottomRight = element.PointToScreen(new Point(element.RenderSize.Width, element.RenderSize.Height)); 

     var bounds = Rect.Empty; 
     bounds.Union(topLeft); 
     bounds.Union(bottomRight); 

     return bounds; 
    } 
1

このレンダリング

 uiElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
     uiElement.Arrange(new Rect(new Point(0, 0), uiElement.DesiredSize)); 
     Size _size = uiElement.DesiredSize; 

を強制するために、これは、少なくとも私の場合にはUIElementはそれをサイズをレンダリングするために前面に働く前に視覚的に表示されていなかった場合こんにちは、私は同様の問題がありました

関連する問題