How to get the scaled size of a WPF visual item

I render the WPF rendering (UserControl) into a bitmap, but the problem is that the rendered image is the size of the UserControl before it is scaled / converted. So, let's say UserControl was designed with a resolution of 200x200 pixels. When I pass BMP, I use UserControl ActualWidth and ActualHeightt, which report 200 and 200 respectively. The problem is that UserControl is on the canvas and is automatically set (set to scale / fill with window size) by about 1200 x 1200 (it changes )

I did some reading and searching and still cannot figure out how to determine the effective size, that is, the size that the control drew on the screen.

I came across this question, which seemed encouraging, but the return transformation does not contain data scaling. Well, that’s true, but both of them 1. Get the position of the element after conversion

Any suggestions on where to look for rendering scaling would be great!

[UPDATE] As I said, I am including the appropriate code:

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

[Update # 2] Added XAML - The Grid element was deleted because it was HUGE and from my reading of the XAML Canvas containing the UserControl keyboard, it was NOT part of the Grid element.

 <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> 
+6
source share
6 answers

I know that a lot of time has passed since the question was asked, but it will not hurt to publish additional information :)

I use this code to find the size (scale) of visual effects using the applied visual transforms.

 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; 
+5
source

If there is a RenderTransform, you are unlikely to be able to determine the size, unless you find serious calculations

In most other cases, you can get the size of the FrameworkElement using the ActualHeight and ActualWidth properties. However, these properties will give you a bounding box size that is sufficient for the scenario you are describing.

+1
source

Hi, I had a similar problem if the visual did not display earlier in order to force this rendering

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

this works, at least in my case, before the UIElement displays its size

+1
source

You say you use the width and height of Visual. Firstly, there are two problems. A Visual, http://msdn.microsoft.com/en-us/library/system.windows.media.visual.aspx has no properties for height and width.

Now, if you have a FrameworkElement that has the Height and Width property, are you using the Height and Width, ActualHeight, and ActualWidth properties? If you do not, then these are the properties you are looking for.

If you use them, or you do not use FrameworkElement, you should post the code.

0
source

If you can use animation to perform Transform , then the animation exposes the Completed event. This should be a good place to retrieve the new resized.

0
source
  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; } 
0
source

Source: https://habr.com/ru/post/898956/


All Articles