C#抓取当前屏幕并保存为图片的方法
作者:work24 发布时间:2023-09-27 08:39:43
标签:C#,屏幕,图片
本文实例讲述了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#程序设计有所帮助。


猜你喜欢
- PDF中的墨迹注释(Ink Annotation),表现为徒手涂鸦式的形状;该类型的注释,可任意指定形状顶点的位置及个数,通过指定的顶点,程
- 这篇文章主要介绍了SpringMVC的执行流程及组件详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 本文实例讲述了Android开发实现Launcher3应用列表修改透明背景的方法。分享给大家供大家参考,具体如下:Launcher时开机完成
- 程序性能的主要表现点:执行速度:程序的反映是否迅速,响应时间是否足够短内存分配:内存分配是否合理,是否过多地消耗内存或者存在内存泄漏启动时间
- 如何打印GC日志排查问题在工作当中,有时候我们会需要打印GC的相关信息来定位问题。该如何做呢?先来看个示例public static voi
- 目录Java 的Stream流一、定义二、操作的特征三、代码示例1、生成流2、forEach 迭代3、limit方法用于获取指定数量的流4、
- 目录ActivityView常用事件接口设置监听的几种方法1)让Activity实现接口2) 匿名内部类3) onClick可以在xml中设
- 一、图形DrawableDrawable类型表达了各种各样的图形,包括图片、色块、画板、背景等。包含图片在内的图形文件放在res目录的各个d
- 本文实例讲述了C#交错数组用法。分享给大家供大家参考。具体分析如下:交错数组是数组的数组,交错数组的元素可以是不同的尺寸和大小。交错数组有时
- 前言:在看这个变更之前,我们需要回忆下 Android 12 的一个安全性变更, 即声明了 <intent-filter&g
- Android-webview和js互相调用Android 和 H5 都是移动开发应用的非常广泛。市面上很多App都是使用Android开发
- 目前做的项目使用的是MAVEN来管理jar包,这也是我第一次接触maven,感觉非常好,再也不用一个一个去添加和下载jar包了,直接在mav
- 随着互联网的飞跃式发展,移动支付已越来越受欢迎并且已成为常态,很多三方支付公司推出了很多支付方式如快捷支付、认证支付、扫码支付等等。快捷支付
- 前言平时日常开发用得最多是Http通讯,接口调试也比较简单的,也有比较强大的框架支持(OkHttp)。个人平时用到socket通讯的地方是A
- 本文介绍 Spring Boot 项目中整合 ElasticSearch 并实现 CRUD 操作,包括分页、滚动等功能。之前在公司使用 ES
- 之前使用OnSharedPreferenceChangeListener,遇到了点小问题,就是有些时候OnSharedPreferenceC
- Java中有四种权限修饰符publicprotected(default)private同一个类yesyesyesyes同一个包yesyes
- C#将DLL打包到程序中有时候我们的程序中包含一些添加的DLL文件,使用起来不方便,我们可以把这些DLL文件打包到程序集中,只剩下一个EXE
- 有些情况下,在开发一些C#小项目的时候,交付给别人用的时候就是单独EXE文件,但是若涉及什么EXCEL,图片什么的时候,比较麻烦,这时候可以
- Statement 和 PreparedStatement之间的关系和区别. 关系:Prepa