Crear capturas de pantalla de diferentes maneras en C#

Crear capturas de pantalla de diferentes maneras en C#

Para reportar errores, una aplicación destinada a crear capturas de pantalla etc, cual sea el motivo por el que lo necesites, está claro que una imágen dice más que 1000 palabras. En este articulo aprenderás a crear una captura de pantalla completa o solamente de una ventana en especifico.

Te ofreceremos 2 métodos diferentes con los que podrás crear una captura de pantalla de acuerdo a la manera en la que lo necesites. Si quieres usar los métodos que requieren la clase ScreenCapture, necesitarás crearla primero con el siguiente código (recuerda cambiar el namespace de acuerdo a tu proyecto):

Nota

No necesitas esta clase si usas el método que no requieren la clase ScreenCapture, pues la segunda opcion solo usa el método CopyFromScreen.

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

namespace CambiaEsteNamespace
{
    /// <summary>
    /// Provee funciones para crear capturas de pantalla o de una ventana en particular y luego guardarla en un archivo.
    /// </summary>
    public class ScreenCapture
    {
        /// <summary>
        /// Crea un objeto de Imagen que contiene una captura de pantalla completa.
        /// </summary>
        /// <returns></returns>
        public Image CaptureScreen()
        {
            return CaptureWindow(User32.GetDesktopWindow());
        }

        /// <summary>
        /// Create un objeto imagen que contiene una captura de pantalla de la ventana actual
        /// </summary>
        /// <param name="handle">La instancia Handle de la ventana (En windows forms, es obtenida a traves de la propiedad Handle)</param>
        /// <returns></returns>
        public Image CaptureWindow(IntPtr handle)
        {
            // obtener hDC de la ventana deseada
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            // Obtener el tamano
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;
            // Crea un contexto en el que se copiara la imagen
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            // create a bitmap we can copy it to,
            // using GetDeviceCaps to get the width/height
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            // Seleccionar el objeto bitmap 
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            // finalizar bitblt
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            // Restaurar seleccion
            GDI32.SelectObject(hdcDest, hOld);
            // Limpiar
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            // Obtener una imagen .NET image del bitmap
            Image img = Image.FromHbitmap(hBitmap);
            // Liberar objeto Bitmab
            GDI32.DeleteObject(hBitmap);
            return img;
        }
        /// <summary>
        /// Captura una captura de pantalla de la ventana especifica y la guarda a un archivo
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
        {
            Image img = CaptureWindow(handle);
            img.Save(filename, format);
        }

        /// <summary>
        /// Captura una imagen del escritorio completo y la guarda a un archivo.
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        public void CaptureScreenToFile(string filename, ImageFormat format)
        {
            Image img = CaptureScreen();
            img.Save(filename, format);
        }

        /// <summary>
        /// Clase ayudante que contiene functiones de la API gdi32
        /// </summary>
        private class GDI32
        {

            public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
            [DllImport("gdi32.dll")]
            public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
                int nWidth, int nHeight, IntPtr hObjectSource,
                int nXSrc, int nYSrc, int dwRop);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
                int nHeight);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
        }

        /// <summary>
        /// Clase ayudante que contiene functiones de la API User32
        /// </summary>
        private class User32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }
            [DllImport("user32.dll")]
            public static extern IntPtr GetDesktopWindow();
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hWnd);
            [DllImport("user32.dll")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
        }
    }
}

Captura de pantalla de la ventana actual

Tanto como para la captura de pantalla completa y de la ventana actual hay 2 métodos, uno usando la clase mencionada anteriormente y otro usando la librería Drawing de Windows.

Para crear una captura de pantalla solamente de la ventana actual, puedes usar la siguiente clase que te permite crear diferentes tipos de capturas.

Primero no olvides incluir los siguientes tipos en tu clase (donde usarás los métodos) para poder acceder a los métodos que necesitamos:

using System.Drawing;
using System.Drawing.Imaging;

Ahora para crear una captura de pantalla de la ventana actual, usa el siguiente método en tu clase:

/// <summary>
/// Crea una captura de pantalla de la ventana actual.
/// Requiere la Clase ScreenCapture
/// </summary>
/// <param name="filepath"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
private void WindowScreenshot(String filepath, String filename, ImageFormat format)
{
    ScreenCapture sc = new ScreenCapture();

    string fullpath = filepath + "\\" + filename;

    sc.CaptureWindowToFile(this.Handle, fullpath, format);
}

// Usar de la siguiente manera:

WindowScreenshot(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "window_screenshot.jpg", ImageFormat.Jpeg);

Ahora, la otra manera es usar el método CopyFromScreen de la clase Graphics de .NET. Puedes usar el siguiente método para crear la captura de pantalla de la ventana actual sin la necesidad de usar otra clase:

/// <summary>
/// Crea una captura de pantalla de la ventana actual usando  el método CopyFromScreen de manera relativa a la localización del form
/// </summary>
/// <param name="filepath"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
private void WindowScreenshotWithoutClass(String filepath, String filename, ImageFormat format)
{
    Rectangle bounds = this.Bounds;

    using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
        }

        string fullpath = filepath + "\\" + filename;

        bitmap.Save(fullpath,format);
    }
}


// Usalo de la siguiente manera 
WindowScreenshotWithoutClass(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "window_screen_noclass.jpg", ImageFormat.Jpeg);

Captura de pantalla completa

Para la creación de una captura de pantalla completa, puedes usar la librería Drawing de Windows o usar la clase ScreenCapture mencionada al inicio del articulo.

El primer método genera una captura de pantalla completa y la guarda en un directorio, para ello usaremos el método CopyFromScreen de la clase Graphics de .NET.

Primer no olvides agregar los siguiente tipos en la clase en la que necesitas generar las capturas de pantalla:

using System.Drawing;
using System.Drawing.Imaging;

Ahora generala y guardala en un directorio especifico usando el siguiente método:

/// <summary>
/// Genera una captura de pantalla completa  y la guarda en un directorio con un nombre personalizado
/// Espera además el formato de imágen
/// </summary>
/// <param name="filepath"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
private void FullScreenshot(String filepath,String filename,ImageFormat format)
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }

        string fullpath = filepath + "\\" + filename;

        bitmap.Save(fullpath, format);
    }
}

// Usalo de la siguiente manera
FullScreenshot(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "screenshot.jpg", ImageFormat.Jpeg);

Y si quieres crear la captura de pantalla usando la clase ScreenCapture, usa el siguiente método en su lugar:

/// <summary>
///  Crea una captura de pantalla completa usando ScreenCapture();
/// </summary>
/// <param name="filepath"></param>
/// <param name="filename"></param>
/// <param name="format"></param>
private void FullScreenshotWithClass(String filepath, String filename, ImageFormat format)
{
    ScreenCapture sc = new ScreenCapture();
    Image img = sc.CaptureScreen();

    string fullpath = filepath + "\\" + filename;

    img.Save(fullpath, format);
}


// Y usalo de la siguiente manera:
FullScreenshotWithClass(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "screenshotfull_class.jpg", ImageFormat.Jpeg);

Más información

  • Recuerda que puedes cambiar el formato de la imagen cambiando la extension en el nombre y además el tipo de formato como argument (ImageFormat). Esta clase soporta los siguientes formatos:
    • ImageFormat.Jpeg
    • ImageFormat.Gif
    • ImageFormat.Tiff
    • ImageFormat.Icon
    • ImageFormat.MemoryBmp
    • ImageFormat.Bmp
    • ImageFormat.Exif

Que te diviertas !

Esto podría ser de tu interes

Conviertete en un programador más sociable