none
WPF Screen Capture (with Rectangle) RRS feed

  • Question

  • Is there any Screen Capture class for WPF that allows you to capture Whole Screen and Specified Rectangle ?

    Also, a simple code that will allow you to draw a WPF Rectangle by MouseDown & MouseMove method, will be greatly appreciated.

    Thanks
    Friday, August 28, 2009 9:44 AM

Answers

  • To capture the screen in a bimap you can do this:

    private static BitmapSource CopyScreen()
    {
        using (var screenBmp = new Bitmap(
            (int)SystemParameters.PrimaryScreenWidth,
            (int)SystemParameters.PrimaryScreenHeight,
            PixelFormat.Format32bppArgb))
        {
            using (var bmpGraphics = Graphics.FromImage(screenBmp))
            {
                bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
                return Imaging.CreateBitmapSourceFromHBitmap(
                    screenBmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
        }
    }
    

    You will need add a reference to System.Drawing, and the following namespaces:

    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Media.Imaging;




     


    http://weblogs.asp.net/marianor/
    • Proposed as answer by mott555 Friday, August 28, 2009 4:55 PM
    • Marked as answer by farooqaaa Saturday, August 29, 2009 5:55 PM
    Friday, August 28, 2009 12:48 PM

All replies

  • To capture the screen in a bimap you can do this:

    private static BitmapSource CopyScreen()
    {
        using (var screenBmp = new Bitmap(
            (int)SystemParameters.PrimaryScreenWidth,
            (int)SystemParameters.PrimaryScreenHeight,
            PixelFormat.Format32bppArgb))
        {
            using (var bmpGraphics = Graphics.FromImage(screenBmp))
            {
                bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
                return Imaging.CreateBitmapSourceFromHBitmap(
                    screenBmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
        }
    }
    

    You will need add a reference to System.Drawing, and the following namespaces:

    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Media.Imaging;




     


    http://weblogs.asp.net/marianor/
    • Proposed as answer by mott555 Friday, August 28, 2009 4:55 PM
    • Marked as answer by farooqaaa Saturday, August 29, 2009 5:55 PM
    Friday, August 28, 2009 12:48 PM
  • I think that one is not for WPF. It doesn't work for me. It says: 'The type or namespace "drawing" doesn't exist in namespace "System" '.
    Friday, August 28, 2009 1:22 PM
  • You have to reference the System.Drawing.dll assembly for this.
    http://weblogs.asp.net/marianor/
    Friday, August 28, 2009 1:26 PM
  • Thanks a million. Its working!

    Do you have any idea how can I capture a specific area using a Rectangle?
    Friday, August 28, 2009 3:04 PM
  • Well, you can replace the coordinates in the CopyScreen method by your own coordinates:

    private static BitmapSource CopyScreen(int left, int top, int right, int bottom)
    {
        using (var screenBmp = new Bitmap(right - left, bottom - top, PixelFormat.Format32bppArgb))
        {
            using (var bmpGraphics = Graphics.FromImage(screenBmp))
            {
                bmpGraphics.CopyFromScreen(left, top, right, botton, screenBmp.Size);
                return Imaging.CreateBitmapSourceFromHBitmap(
                    screenBmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
        }
    }


    http://weblogs.asp.net/marianor/
    Friday, August 28, 2009 3:26 PM
  • Thanks for the response.

    I don't understand that. How will I put the values if I have a WPF Rectangle? Can you please give me an exmaple? I've used this to test it but it doesn't work:

    CopyScreen(100,200,500,600);

    Can you help me how to put a rectangle's values in that?

    Thanks again.
    Friday, August 28, 2009 5:08 PM
  • source http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/908177f6-637d-4936-b4d6-3884d17ff7a7
    whole work sample for Window and Button on window.
    It store images in root of dick C:/
    No reference the System.Drawing.dll assembly for this. 


    		private void button1_Click(object sender, RoutedEventArgs e)
    		{
    			SaveWindowSnapshot(this, "!!!__!!!__MyWindowSnapshot.jpg");
    
    			// add Button name "button1" before
    			SaveWindowSnapshot(button1, "!!!__!!!__MyButtonSnapshot.jpg");
    		}
    
    
    		private void SaveWindowSnapshot(Visual targetVisual, string fileName)
    		{
    			Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
    			double myDeviceDpiX = m.M11 * 96.0;
    			double myDeviceDpiY = m.M22 * 96.0;
    
    			var imgStream = GrabSnapshotStream(targetVisual, myDeviceDpiX, myDeviceDpiY, ImageFormats.JPG);
    			using (imgStream)
    			{
    				imgStream.Position = 0;
    
    				var fileStream = new FileStream(@"c:/" + fileName, FileMode.OpenOrCreate);
    				using (fileStream)
    				{
    					for (int i = 0; i < imgStream.Length; i++)
    					{
    						fileStream.WriteByte((byte)imgStream.ReadByte());
    					}
    				}
    			}
    		}
    
    
    		public static MemoryStream GrabSnapshotStream(Visual targetVisual, double dpiX, double dpiY, ImageFormats imageFormats)
    		{
    			Rect bounds = VisualTreeHelper.GetDescendantBounds(targetVisual);
    
    			BitmapSource renderTargetBitmap = captureVisualBitmap(
    				targetVisual,
    				dpiX,
    				dpiY
    				);
    
    			BitmapEncoder bitmapEncoder;
    
    			switch (imageFormats)
    			{
    				case ImageFormats.PNG:
    					{
    						bitmapEncoder = new PngBitmapEncoder();
    						break;
    					}
    				case ImageFormats.BMP:
    					{
    						bitmapEncoder = new BmpBitmapEncoder();
    						break;
    					}
    				case ImageFormats.JPG:
    					{
    						bitmapEncoder = new JpegBitmapEncoder();
    						break;
    					}
    				default:
    					throw new NotSupportedException("The Incorrect Logic");
    			}
    
    			bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    
    			// Create a MemoryStream with the image.
    			// Returning this as a MemoryStream makes it easier to save the image to a file or simply display it anywhere.
    			var memoryStream = new MemoryStream();
    			bitmapEncoder.Save(memoryStream);
    
    			return memoryStream;
    		}
    
    
    		private static BitmapSource captureVisualBitmap(Visual targetVisual, double dpiX, double dpiY)
    		{
    			Rect bounds = VisualTreeHelper.GetDescendantBounds(targetVisual);
    			RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
    				(int)(bounds.Width * dpiX / 96.0),
    				(int)(bounds.Height * dpiY / 96.0),
    				dpiX,
    				dpiY,
    
    				//PixelFormats.Default
    				PixelFormats.Pbgra32
    				);
    
    			DrawingVisual drawingVisual = new DrawingVisual();
    			using (DrawingContext drawingContext = drawingVisual.RenderOpen())
    			{
    				VisualBrush visualBrush = new VisualBrush(targetVisual);
    				drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
    			}
    			renderTargetBitmap.Render(drawingVisual);
    
    			return renderTargetBitmap;
    		}
    
    
    
    		public enum ImageFormats
    		{
    			PNG,
    			BMP,
    			JPG
    		}
    
    Wednesday, September 16, 2009 1:50 PM
  • To capture the screen in a bimap you can do this:

    private static BitmapSource CopyScreen()
    
    {
    
        using (var screenBmp = new Bitmap(
    
            (int)SystemParameters.PrimaryScreenWidth,
    
            (int)SystemParameters.PrimaryScreenHeight,
    
            PixelFormat.Format32bppArgb))
    
        {
    
            using (var bmpGraphics = Graphics.FromImage(screenBmp))
    
            {
    
                bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
    
                return Imaging.CreateBitmapSourceFromHBitmap(
    
                    screenBmp.GetHbitmap(),
    
                    IntPtr.Zero,
    
                    Int32Rect.Empty,
    
                    BitmapSizeOptions.FromEmptyOptions());
    
            }
    
        }
    
    }
    
    
    
    

    You will need add a reference to System.Drawing, and the following namespaces:

    using System;
    
    using System.Drawing;
    
    using System.Drawing.Imaging;
    
    using System.Windows;
    
    using System.Windows.Interop;
    
    using System.Windows.Media.Imaging;
    
    




     


    http://weblogs.asp.net/marianor/

    finally! just what I was looking for. Thanks
    Wednesday, April 14, 2010 5:39 AM
  • Brother ,
    I highly request you that please give me a sample project which button click and capture screen and auto save .
    Please
    email: sabbir0186@gmail.com
    • Edited by Sabbir0186 Wednesday, August 24, 2016 4:08 PM
    Wednesday, August 24, 2016 4:08 PM
  • A couple of things.  First the forums are such that a search can bring up answers.  Piggybacking on a posting from 7-8 years ago is not a good idea.  I would suggest that you create a new post with your question.  A link to this post would be appropriate.

    Second, did you try the code presented in this post?


    Lloyd Sheen

    Wednesday, August 24, 2016 4:16 PM