C#抓取当前屏幕并保存为图片的方法

作者:work24 时间:2023-09-27 08:39:43 

本文实例讲述了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 )
   {
    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
   {
    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 = "" )
 {
  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.sina.com.cn" );
  Console.ResetColor( );
  Console.Error.Write( "   Code for graphic screenshot by Ali Hamdar " );
  Console.ForegroundColor = ConsoleColor.DarkGray;
  Console.Error.WriteLine( "https://www.jb51.net" );
  Console.ResetColor( );
  Console.Error.WriteLine( );
  Console.Error.WriteLine( "Written by Rob van der Woude" );
  Console.Error.WriteLine( "http://www.qq.com" );
  return 1;
 }
 #endregion Error Handling
}
#region Read From Console Buffer
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
}

希望本文所述对大家的C#程序设计有所帮助。

标签:C#,屏幕,图片
0
投稿

猜你喜欢

  • Java如何提供给第三方使用接口方法详解

    2022-07-22 19:59:19
  • 详解Java中List的正确的删除方法

    2021-09-19 13:20:42
  • SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)

    2023-10-02 05:20:58
  • 深入了解SparkSQL的运用及方法

    2023-06-08 13:43:27
  • .Net WInform开发笔记(三)谈谈自制控件(自定义控件)

    2021-06-11 10:25:11
  • Android启动页出现白屏、黑屏的解决方案

    2022-08-23 21:11:52
  • SpringMVC框架整合Junit进行单元测试(案例详解)

    2022-04-10 20:53:37
  • java中的key接口解析

    2023-09-22 14:44:00
  • 一篇文章带你Java Spring开发入门

    2021-06-25 10:04:15
  • C#中Params的用法

    2023-06-03 22:23:27
  • Android ListView与ScrollView冲突的解决方法总结

    2022-09-05 21:44:03
  • Java任意长度byte数组转换为int数组的方法

    2023-02-15 15:26:32
  • JavaWeb Servlet实现文件上传与下载功能实例

    2023-06-16 16:41:27
  • 一篇文章带你深入了解Java基础(2)

    2023-12-09 21:06:23
  • 详谈Java中的Object、T(泛型)、?区别

    2022-06-11 21:13:11
  • 详解DES加密算法的原理与Java实现

    2021-06-22 06:56:19
  • C++深浅拷贝和写时拷贝图文详解

    2021-06-07 00:12:58
  • java取两个字符串的最大交集

    2021-07-30 17:23:08
  • Java中常用的设计模式之观察者模式详解

    2023-07-27 12:32:52
  • C#实现串口调试工具

    2022-06-09 12:04:04
  • asp之家 软件编程 m.aspxhome.com