Click here to Skip to main content
15,897,518 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The program below creates a snapshot with the content of the main window of the application itself. However the quality of the produced picture is not equivalent to the print screen program of windows 10, which produces the desired result.

Here is a snapshot of the program running, taken with the print screen program of windows 10, zoomed in:

https://ibb.co/wz4pb4d

And here is the snapshot that the program below is producing, zoomed in:

https://ibb.co/DLsNb8X

Is there something we can try to improve the quality of the snapshot that this program produse?

I tried Bitmap Encoder but is the same result , just without transparency, (Don't need to have transparency) also tried some other Pixel Formats but I get errors, only Pbgra32 seems to work as the program is.

Thanks in advance

What I have tried:

C#
<pre> if (e.Key == Key.P)
            {
                //Set scrollviewer's Content property as UI element to capture full content
                FrameworkElement element = UxVisual as FrameworkElement;
                Uri path = new Uri(@"C:\Users\4gry\Desktop\screenshot.png");
                CaptureScreen(element, path);
            }

        }
            public void CaptureScreen(FrameworkElement source, Uri destination)
            {
            RenderOptions.SetEdgeMode(source, EdgeMode.Aliased);
            try
                {
                    double Height, ActualHeight, Width, ActualWidth;

                    Height = ActualHeight = source.RenderSize.Height;
                    Width = ActualWidth = source.RenderSize.Width;

                    //Specification for target bitmap like width/height pixel etc.
                    RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)ActualWidth, (int)ActualHeight, 96, 96, PixelFormats.Pbgra32);
                    //creates Visual Brush of UIElement
                    VisualBrush visualBrush = new VisualBrush(source);

                    DrawingVisual drawingVisual = new DrawingVisual();
                    using (DrawingContext drawingContext = drawingVisual.RenderOpen())
                    {
                        //draws image of element
                        drawingContext.DrawRectangle(visualBrush, null, new Rect(source.RenderSize));
                    }
                    

                    //renders image
                    renderTarget.Render(drawingVisual);

                    //PNG encoder for creating PNG file
                    PngBitmapEncoder encoder = new PngBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(renderTarget));
                    using (FileStream stream = new FileStream(destination.LocalPath, FileMode.Create, FileAccess.Write))
                    {
                        encoder.Save(stream);
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }


XAML

<Window x:Name="mainwindow" x:Class="WpfApp2.MainWindow"
        
        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:WpfApp2"
        mc:Ignorable="d"
        Title="mainwindow" Height="397.265" Width="603.147" Icon="images2/Untitled-1.gif" ResizeMode="CanMinimize" WindowStartupLocation="Manual" AutomationProperties.Name="Grid" IsTabStop="True" KeyDown="Mainwindow_KeyDown" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0">
    <Border x:Name="UxVisual" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="367" Margin="10,0,0,0" VerticalAlignment="Top" Width="583">
        <Grid Margin="0,0,0,13">

            <Image Stretch="None" Source="images2/screenshot copy.gif" IsEnabled="False" Margin="0,0,-28,0" HorizontalAlignment="Left" Width="625" Height="347" VerticalAlignment="Top"/>

            <Image x:Name="linevertical" HorizontalAlignment="Left" Height="343" Margin="108,76,-21,0" VerticalAlignment="Top" Width="705" Source="images2/Untitled-1.gif" Stretch="None" Visibility="Hidden" RenderTransformOrigin="0.46,0.52"/>
            <Image x:Name="lineo" HorizontalAlignment="Left" Height="171" Margin="173,76,0,0" VerticalAlignment="Top" Width="193" Source="images2/Untitled-3.gif" Stretch="None" Visibility="visible"/>
            <Image HorizontalAlignment="Left" Height="100" Margin="10,16,0,0" VerticalAlignment="Top" Width="189" Source="images2/Untitled-1.gif" Stretch="None" Visibility="hidden"/>
            <Image HorizontalAlignment="Left" Height="100" Margin="73,10,0,0" VerticalAlignment="Top" Width="100" Source="images2/Untitled-3.gif" Stretch="None" Visibility="visible"/>
            <Button HorizontalAlignment="Left" Margin="173,61,0,0" VerticalAlignment="Top" Width="225" Height="121" Opacity="0"  Click="Button_Click"/>
            <Button Content="" HorizontalAlignment="Left" Margin="464,247,0,0" VerticalAlignment="Top" Width="194" Height="144" Opacity="0" Click="Button_Click_1"/>
            <Image HorizontalAlignment="Left" Height="100" Margin="428,-11,-40,0" VerticalAlignment="Top" Width="206" Stretch="None" Source="images2/Untitled-1.gif"/>

        </Grid>
    </Border>
</Window>
Posted
Updated 20-Apr-19 23:29pm
v6

I create the "Visual" (i.e. FrameworkElement) that I want to capture and then use the ACTUAL dimensions:
RenderTargetBitmap rtb = new RenderTargetBitmap(
            (int) printVisual.ActualWidth,
            (int) printVisual.ActualHeight, 96, 96, PixelFormats.Pbgra32 );


Quote:
FrameworkElement is the WPF framework-level implementation class that builds on UIElement, and adds specific interactions with the WPF framework level. FrameworkElement adds and defines the following capabilities:

Additional framework-specific layout characteristics

Support for richer metadata reporting on properties

Class-specific implementation of certain input base classes and their attached properties or attached events

Style support

Further animation support


In other words, you should be working with FrameworkElement and not UI element. I frequently use a reference to a "Border" (visible or not) around my main target visual.
 
Share this answer
 
v3
Comments
tool__ 20-Apr-19 12:42pm    
I'm not sure how to use your code, if you can modify the code i posted above for me...

Anyway you are probably right that the problem has to do with some resize that going on... I notised that the prodused picture of the snapshot is slightly smaler then the window of the actual program that runing... probably smaller enough to produce that blury effect...
However I'm almost ready to give up the snapshot idea for good, because of this problem and for some other alignment issues that occurred... the result is disappointing... I'm going for a simpler program, with code I can handle, less functions for the program more brain cells for me.

Thenks for your time
[no name] 20-Apr-19 13:59pm    
You're hooking up to this nebulus thing called Windows.Content and casting as a UI Element when I told you to use a FrameWork element like a Border for a reference. What part am I not clear on?
tool__ 20-Apr-19 14:27pm    
I don't understand how use a FrameWork element like a Border for a reference... please give me a code example
[no name] 20-Apr-19 14:37pm    
<window>
<border x:name="UxVisual">
... stuff in border, like grid with text boxes.



You can do it all in memory without the window but in your case it's probably better you try WYSIWYG. Now, reference the Border by name (in this case) AS A FRAMEWORK ELEMENT (instead of using WINDOW.CONTENT as a "dumb" UI ELEMENT). Or do you not understand any of the code you posted?
tool__ 20-Apr-19 15:19pm    
I edited the code in the original post check it please.
in this line:
FrameworkElement element = UxVisual.Content as FrameworkElement;

The word 'Content' is underlined red and it say:

'Border' does not contain a definition for 'content' and no accessible extension method 'Content' accepting a first argument of type 'Border' could be found. (are you missing a using directive or an assembly refereance?)
C#
PixelFormats.Pbgra32

Try a format with a higher resolution.
 
Share this answer
 
Comments
tool__ 20-Apr-19 8:09am    
i have tried all the pixel formats of this page,
https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.pixelformats?view=netframework-4.8
none works, it say the format is not supported, except for Pbgra32
Richard MacCutchan 20-Apr-19 8:26am    
Then I guess you have to live with the lower image quality.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900