2011-10-10 28 views
6

Sto eseguendo il rendering di un oggetto WPF Visual (UserControl) in una bitmap, ma il problema è che l'immagine renderizzata è la dimensione di UserControl prima di essere ridimensionata/trasformata. Quindi diciamo che UserControl è stato progettato a 200x200 pixel. Quando eseguo il rendering su BMP, utilizzo ActualWidth e ActualHeightt di UserControl che riportano rispettivamente 200 e 200. Problema: UserControl si trova in una tela e viene dimensionato automaticamente (impostato su scala/riempimento con la dimensione della finestra) su qualcosa più vicino a 1200 x 1200 (cambia)Come ottenere la dimensione ridimensionata di un elemento WPF Visual

Ho letto e cercato e fino ad ora posso 'capire come determinare la dimensione effettiva, cioè la dimensione del controllo viene dipinto sullo schermo.

Mi sono imbattuto in questa domanda che sembrava speranzosa ma la trasformazione restituita non contiene dati di ridimensionamento. Bene, ma sono entrambi 1. Get element position after transform

Qualsiasi suggerimento su dove cercare il rendering in scala sarebbe fantastico!

[UPDATE] Come suggerito, sto compreso il relativo codice:

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); 
} 

[Aggiornamento # 2] Aggiunta la XAML - L'elemento griglia è stato rimosso perché era enorme e dal mio leggendo XAML il Canvas contenente la tastiera UserControl NON faceva parte dell'elemento 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

Che tipo di trasformazione viene applicata al controllo? LayoutTransform o/e RenderTransform? Cosa intendi per "auto dimensionato"? –

+0

@Erno - Onestamente non ne sono completamente sicuro. Sono nuovo, sono più nuovo di WPF e non ho ancora una conoscenza degli strumenti di Layout. Sembra che UserControl si trovi all'interno di una tela configurata per allungare in larghezza e altezza –

+0

quindi mostrarci il codice in modo che possiamo aiutarti. –

risposta

5

Conosco un sacco di tempo trascorso dal momento che la domanda è stata posta, ma non fa male a postare qualche info in più :)

io uso questo codice per trovare dimensione (scala) di immagini con applicata render trasformare (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

Nota che più in generale, si può semplicemente calcolare i limiti del visual relativo al genitore: 'Rect bounds = t .TransformBounds (new Rect (new Size (transformVisual.ActualWidth, transformVisual.ActualHeight)); '. Ovviamente, affinché funzioni,' transformVisual' deve essere un 'FrameworkElement', invece di un semplice' Visual' (quest'ultimo non ha informazioni dimensionali da solo). –

0

Si dice di utilizzare la larghezza e l'altezza del Visual. In primo luogo, ci sono due problemi. Un Visual, http://msdn.microsoft.com/en-us/library/system.windows.media.visual.aspx non ha alcuna proprietà per Altezza e Larghezza.

Ora, se si dispone di un oggetto FrameworkElement, che ha una proprietà Height e Width, si utilizzano le proprietà Height e Width o le proprietà ActualHeight e ActualWidth? Se non lo sei, allora quelle sono le proprietà che stai cercando.

Se li si utilizza o non si utilizza un FrameworkElement, è necessario inserire del codice.

+0

Ci scusiamo per la confusione. In realtà è un UserControl e sto usando ActualWidth e ActualHeight (ho aggiornato il mio messaggio originale per chiarire questo) –

0

Se è possibile utilizzare l'animazione per eseguire lo Transform, l'animazione fornisce l'evento Completed. Questo dovrebbe essere un buon posto per estrarre nuove dimensioni trasformate.

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

Hi Ho avuto un problema simile se il visivo non era visualizzata prima di costringere questo rendering

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

questo funziona, almeno nel mio caso alla ribalta il UIElement per renderlo Size

Problemi correlati