C#將當前屏幕抓取下來保存為圖片

xf3f 9年前發布 | 2K 次閱讀 C#

這是一個C#實現的屏幕抓取程序,可以抓取整個屏幕保存為指定格式的圖片,并且保存當前控制臺緩存到文本

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace RobvanderWoude { class PrintScreen { static int Main( string[] args ) { try { string output = string.Empty; bool overwrite = false; bool text = false; ImageFormat type = null;

            #region Command Line parsing

            if ( args.Length == 0 )
            {
                return WriteError( );
            }

            foreach ( string arg in args )
            {
                switch ( arg.ToUpper( ).Substring( 0, 2 ) )
                {
                    case "/?":
                        return WriteError( );
                    case "/O":
                        overwrite = true;
                        break;
                    case "/T":
                        if ( text )
                        {
                            return WriteError( "Cannot capture current window as bitmap" );
                        }
                        switch ( arg.ToUpper( ).Substring( 3 ) )
                        {
                            case "BMP":
                                type = ImageFormat.Bmp;
                                break;
                            case "GIF":
                                type = ImageFormat.Gif;
                                break;
                            case "JPG":
                            case "JPEG":
                                type = ImageFormat.Jpeg;
                                break;
                            case "PNG":
                                type = ImageFormat.Png;
                                break;
                            case "TIF":
                            case "TIFF":
                                type = ImageFormat.Tiff;
                                break;
                            case "TXT":
                                text = true;
                                break;
                            default:
                                return WriteError( "Invalid file format: \"" + arg.Substring( 4 ) + "\"" );
                        }
                        break;
                    default:
                        output = arg;
                        break;
                }
            }

            // Check if directory exists
            if ( !Directory.Exists( Path.GetDirectoryName( output ) ) )
            {
                return WriteError( "Invalid path for output file: \"" + output + "\"" );
            }

            // Check if file exists, and if so, if it can be overwritten
            if ( File.Exists( output ) )
            {
                if ( overwrite )
                {
                    File.Delete( output );
                }
                else
                {
                    return WriteError( "File exists; use /O to overwrite existing files." );
                }
            }

            if ( type == null && text == false )
            {
                string ext = Path.GetExtension( output ).ToUpper( );
                switch ( ext )
                {
                    case ".BMP":
                        type = ImageFormat.Bmp;
                        break;
                    case ".GIF":
                        type = ImageFormat.Gif;
                        break;
                    case ".JPG":
                    case ".JPEG":
                        type = ImageFormat.Jpeg;
                        break;
                    case ".PNG":
                        type = ImageFormat.Png;
                        break;
                    case ".TIF":
                    case ".TIFF":
                        type = ImageFormat.Tiff;
                        break;
                    case ".TXT":
                        text = true;
                        break;
                    default:
                        return WriteError( "Invalid file type: \"" + ext + "\"" );
                        return 1;
                }
            }

            #endregion Command Line parsing

            if ( text )
            {
                // Based on code by Simon Mourier (http://www.softfluent.com/)
                // http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
                string readtext = string.Empty;
                for ( short i = 0; i < (short) Console.BufferHeight; i++ )
                {
                    foreach ( string line in ConsoleReader.ReadFromBuffer( 0, i, (short) Console.BufferWidth, 1 ) )
                    {
                        readtext += line + "\n";
                    }
                }
                StreamWriter file = new StreamWriter( output );
                file.Write( readtext );
                file.Close( );
            }
            else
            {
                // Based on code by Ali Hamdar (http://alihamdar.com/)
                // http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/79efecc4-fa6d-4078-afe4-bb1379bb968b
                // Default values for full screen
                int width = Screen.PrimaryScreen.Bounds.Width;
                int height = Screen.PrimaryScreen.Bounds.Height;
                int top = 0;
                int left = 0;
                Bitmap printscreen = new Bitmap( width, height );
                Graphics graphics = Graphics.FromImage( printscreen as Image );
                graphics.CopyFromScreen( top, left, 0, 0, printscreen.Size );
                printscreen.Save( output, type );
            }
            return 0;
        }
        catch ( Exception e )
        {
            Console.Error.WriteLine( e.Message );
            return 1;
        }
    }
    #region Error Handling

    public static int WriteError( string errorMessage = "" )
    {
        /*
        PrintScreen,  Version 1.00
        Save a screenshot as image or save the current console buffer as text

        Usage:   PRINTSCREEN  outputfile  [ /T:type ]  [ /O ]

        Where:   outputfile   is the file to save the screenshot or text to
                 /T:type      specifies the file type: BMP, GIF, JPG, PNG, TIF or TXT
                              (only required if outputfile extension is different)
                 /O           overwrites an existing file

        Credits: Code to read console buffer by Simon Mourier http://www.softfluent.com
                 Code for graphic screenshot by Ali Hamdar    http://alihamdar.com

        Written by Rob van der Woude
        http://www.robvanderwoude.com
        */

        Console.ResetColor( );
        if ( string.IsNullOrEmpty( errorMessage ) == false )
        {
            Console.Error.WriteLine( );
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Error.Write( "ERROR:  " );
            Console.ForegroundColor = ConsoleColor.White;
            Console.Error.WriteLine( errorMessage );
            Console.ResetColor( );
        }
        Console.Error.WriteLine( );
        Console.Error.WriteLine( "PrintScreen,  Version 1.10" );
        Console.Error.WriteLine( "Save a screenshot as image or save the current console buffer as text" );
        Console.Error.WriteLine( );
        Console.Error.Write( "Usage:   " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.WriteLine( "PRINTSCREEN  outputfile  [ /T:type ]  [ /O ]" );
        Console.ResetColor( );
        Console.Error.WriteLine( );
        Console.Error.Write( "Where:   " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "outputfile" );
        Console.ResetColor( );
        Console.Error.WriteLine( "   is the file to save the screenshot or text to" );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "         /T:type" );
        Console.ResetColor( );
        Console.Error.Write( "      specifies the file type: " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "BMP" );
        Console.ResetColor( );
        Console.Error.Write( ", " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "GIF" );
        Console.ResetColor( );
        Console.Error.Write( ", " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "JPG" );
        Console.ResetColor( );
        Console.Error.Write( ", " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "PNG" );
        Console.ResetColor( );
        Console.Error.Write( ", " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "TIF" );
        Console.ResetColor( );
        Console.Error.Write( " or " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.WriteLine( "TXT" );
        Console.ResetColor( );
        Console.Error.Write( "                      (only required if " );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "outputfile" );
        Console.ResetColor( );
        Console.Error.WriteLine( " extension is different)" );
        Console.ForegroundColor = ConsoleColor.White;
        Console.Error.Write( "         /O" );
        Console.ResetColor( );
        Console.Error.WriteLine( "           overwrites an existing file" );
        Console.Error.WriteLine( );
        Console.Error.Write( "Credits: Code to read console buffer by Simon Mourier " );
        Console.ForegroundColor = ConsoleColor.DarkGray;
        Console.Error.WriteLine( "http://www.softfluent.com" );
        Console.ResetColor( );
        Console.Error.Write( "         Code for graphic screenshot by Ali Hamdar    " );
        Console.ForegroundColor = ConsoleColor.DarkGray;
        Console.Error.WriteLine( "http://alihamdar.com" );
        Console.ResetColor( );
        Console.Error.WriteLine( );
        Console.Error.WriteLine( "Written by Rob van der Woude" );
        Console.Error.WriteLine( "http://www.robvanderwoude.com" );
        return 1;
    }
    #endregion Error Handling

}

#region Read From Console Buffer

// ConsoleReader by Simon Mourier (http://www.softfluent.com/)
// http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
public class ConsoleReader
{
    public static IEnumerable<string> ReadFromBuffer( short x, short y, short width, short height )
    {
        IntPtr buffer = Marshal.AllocHGlobal( width * height * Marshal.SizeOf( typeof( CHAR_INFO ) ) );
        if ( buffer == null )
            throw new OutOfMemoryException( );

        try
        {
            COORD coord = new COORD( );
            SMALL_RECT rc = new SMALL_RECT( );
            rc.Left = x;
            rc.Top = y;
            rc.Right = (short) ( x + width - 1 );
            rc.Bottom = (short) ( y + height - 1 );

            COORD size = new COORD( );
            size.X = width;
            size.Y = height;

            const int STD_OUTPUT_HANDLE = -11;
            if ( !ReadConsoleOutput( GetStdHandle( STD_OUTPUT_HANDLE ), buffer, size, coord, ref rc ) )
            {
                // 'Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.)
                throw new Win32Exception( Marshal.GetLastWin32Error( ) );
            }

            IntPtr ptr = buffer;
            for ( int h = 0; h < height; h++ )
            {
                StringBuilder sb = new StringBuilder( );
                for ( int w = 0; w < width; w++ )
                {
                    CHAR_INFO ci = (CHAR_INFO) Marshal.PtrToStructure( ptr, typeof( CHAR_INFO ) );
                    char[] chars = Console.OutputEncoding.GetChars( ci.charData );
                    sb.Append( chars[0] );
                    ptr += Marshal.SizeOf( typeof( CHAR_INFO ) );
                }
                yield return sb.ToString( );
            }
        }
        finally
        {
            Marshal.FreeHGlobal( buffer );
        }
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct CHAR_INFO
    {
        [MarshalAs( UnmanagedType.ByValArray, SizeConst = 2 )]
        public byte[] charData;
        public short attributes;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct COORD
    {
        public short X;
        public short Y;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct SMALL_RECT
    {
        public short Left;
        public short Top;
        public short Right;
        public short Bottom;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct CONSOLE_SCREEN_BUFFER_INFO
    {
        public COORD dwSize;
        public COORD dwCursorPosition;
        public short wAttributes;
        public SMALL_RECT srWindow;
        public COORD dwMaximumWindowSize;
    }

    [DllImport( "kernel32.dll", SetLastError = true )]
    private static extern bool ReadConsoleOutput( IntPtr hConsoleOutput, IntPtr lpBuffer, COORD dwBufferSize, COORD dwBufferCoord, ref SMALL_RECT lpReadRegion );

    [DllImport( "kernel32.dll", SetLastError = true )]
    private static extern IntPtr GetStdHandle( int nStdHandle );

}
#endregion Read From Console Buffer

}</pre>

 本文由用戶 xf3f 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!