Problem with saving Gauge into an image file

10 posts, 1 answers
  1. Souchard
    Souchard avatar
    3 posts
    Member since:
    Mar 2012

    Posted 26 Mar 2012 Link to this post

    Hi,

    With the old gauge (beta), I create some gauge controls and directly (without display) save the result in an Image file.
    With the new gauge, I have some probleme with the ticks and label display (as you can see in the attached file).

    The code I use is :
    UC = new CircularGauge(); // Usercontrol WPF
    UC.Width = 200; UC.Height = 200;
     
    UC.Measure(new System.Windows.Size(UC.Width, UC.Height));
    UC.Arrange(new Rect(0.0, 0.0, UC.Width, UC.Height));
    UC.UpdateLayout();
     
    RenderTargetBitmap oTargetBitmap = new RenderTargetBitmap((int)UC.Width, (int)UC.Height, 96.0, 96.0, System.Windows.Media.PixelFormats.Default);
    oTargetBitmap.Render(UC);
             
    PngBitmapEncoder oPngBitmapEncoder = new PngBitmapEncoder();
    oPngBitmapEncoder.Frames.Add(BitmapFrame.Create(oTargetBitmap));
    oPngBitmapEncoder.Save(msGaugeImage);

    What is wrong in my approch ?
    Is there a other way to do this ?

    Thanks,

    Yves
  2. Answer
    Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 28 Mar 2012 Link to this post

    Hi Souchard,

    The gauge control renders some its elements using the Loaded event. So, you should add the control to the visual tree. It could be done using any container which is already rendered.
    As alternative you can use the instance of the HwndSource class which raises the Loaded event for its RootVisual element.
    Also I have recommend to use the ExportExtensions.ExportToImage method. It is more useful than a code which renders the user control to bitmap.
    The sample code is below.
    using System.IO;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Media.Imaging;
    using Microsoft.Win32;
    using Telerik.Windows.Media.Imaging;
     
    namespace ExportToImage
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private SaveFileDialog dialog = new SaveFileDialog();
     
            public MainWindow()
            {
                InitializeComponent();
            }
     
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                dialog.Filter = "Png (*.png)|*.png";
     
                bool? dialogResult = this.dialog.ShowDialog();
                if (dialogResult == true)
                {
                    CircularGauge control = new CircularGauge();
                    control.Width = 200;
                    control.Height = 200;
     
                    using (HwndSource source = new HwndSource(new HwndSourceParameters()))
                    {
                        source.RootVisual = control;
     
                        using (Stream stream = this.dialog.OpenFile())
                        {
                            ExportExtensions.ExportToImage(control, stream, new PngBitmapEncoder());
                        }
                    }
                }
            }
        }
    }

    Regards,
    Andrey Murzov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. UI for WPF is Visual Studio 2017 Ready
  4. Souchard
    Souchard avatar
    3 posts
    Member since:
    Mar 2012

    Posted 28 Mar 2012 Link to this post

    Thank you, it works fine !
  5. Souchard
    Souchard avatar
    3 posts
    Member since:
    Mar 2012

    Posted 03 Apr 2012 Link to this post

    The solution (using HwndSource) work, but I have now a problem of performance.
    This solution spend more time than the other one (Coeff > 5).

    How could I call the gauge rendering method(s) without using HwndSource ?
    Is there another way to create image using telerik control ?

    Thank's,

    Yves
  6. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 06 Apr 2012 Link to this post

    Hello Souchard,

    Unfortunately there is no other way to do it.

    All the best,
    Andrey Murzov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  7. Ordwin
    Ordwin avatar
    5 posts
    Member since:
    Aug 2011

    Posted 17 Apr 2012 Link to this post

    Hello,

    We are facing the same problems after upgrading our wrapper component to the v2012.1.326.40 wpf radcontrols.
    Our component runs on the server and needs to generate the image on first run. However, the radialscale and its labels are not yet rendered at that moment. 
    Is this still possible with the above version or the newest version of the wpf radcontrols? If so, any help would be appreciated.
    If needed I can supply you with a demo project showing the mentioned situation. 

    Furthermore we also see that the radialscale is not rendering properly according the used gauge. For the attached example our xaml looks like:
                    <telerik:RadSemicircleNorthGauge Name="radialGauge" Margin="5" Grid.Row="1" Grid.Column="1" InnerBackground="{Binding GraphFillColor,FallbackValue=WhiteSmoke}">
                        <telerik:RadialScale Name="radialScale" Radius=".7" LabelRotationMode="None" FontFamily="Tahoma" FontSize="{Binding Path=ScaleTitleSettings.TextSize, FallbackValue=14}" LabelLocation="Inside" RangeLocation="Outside">
                            <telerik:RadialScale.Ranges >
                                <telerik:GaugeRange Min="0" Max="50" StartWidth="0.08" EndWidth="0.08" Background="Green" />
                                <telerik:GaugeRange Min="50" Max="80" StartWidth="0.08" EndWidth="0.08" Background="Orange" />
                                <telerik:GaugeRange Min="80" Max="100" StartWidth="0.08" EndWidth="0.08" Background="Red" />
                            </telerik:RadialScale.Ranges>
                            <telerik:RadialScale.Indicators>
                                <telerik:Needle Value="{Binding NeedleValue, FallbackValue=65}" />
                                <telerik:Pinpoint />
                            </telerik:RadialScale.Indicators>                    
                        </telerik:RadialScale>
                    </telerik:RadSemicircleNorthGauge>                
     
    Most likely this is caused by the same issue. Or are we wrong?

    Thanks in advance.

    Best regards,

    Ordwin
  8. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 20 Apr 2012 Link to this post

    Hello Ordwin,

    Actually running the control on the server to generate images is not the way how the gauge control for WPF should be used. There is not any other way to create image of the gauge beside the one which is described below.

    All the best,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  9. Ordwin
    Ordwin avatar
    5 posts
    Member since:
    Aug 2011

    Posted 20 Apr 2012 Link to this post

    Hello Andrey,

    In the Q2 or Q3 2011 release this was still possible. Why has this functionality been dropped in the latest version?
    We like the way the gauges look and we need a single solution for our windows and web client. 
    I already solved my second problem, but currently it is still not drawing the ticks and labels inside the gauge. 
    Is there no way to tweak the gauge control e.g. by adding additional styling to get these inside the gauge on first run?
    Or is there a way to know (e.g. by event) when the control is completely rendered to extract the image?

    Best regards,

    Ordwin
  10. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 25 Apr 2012 Link to this post

    Hi Ordwin,

    We did not change this functionality any way in the new version. The fact that it worked in previous versions is not a feature or part of functionality of the gauge control.
    Anyway I can advice one additional way only. You can try to use the Dispatcher.BeginInvoke method to call the ExportToImage method after you assign the HwndSource.RootVisual property. It is possible that the rendering completes when the method will be invoked. I hope this helps.

    All the best,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  11. Ordwin
    Ordwin avatar
    5 posts
    Member since:
    Aug 2011

    Posted 26 Apr 2012 Link to this post

    Hello Andrey,

    At first I could not get it to work with the HwndSource.RootVisual property, but after digging further into it I finally managed to get it rendering completely. Thanks for all the help.

    Best regards,

    Ordwin
Back to Top
UI for WPF is Visual Studio 2017 Ready