背景
在很多聊天工具中都有一个屏幕截图功能,可以方便的截取屏幕部分区域,以图片的形式传输给对方,使得沟通更加直观。其实不仅在聊天时需要截图,在其他时候我们也需要截图工具,但一般我们都使采用Print Screen按键来截取整个屏幕,然后使用MSPaint再选取部分区域。其实使用C#也很容易实现截图功能。
原理
首先我们也需要对整个屏幕拍一个快照,然后在这个图片上选择一个区域,再截取这部分区域图片即可。另外截取部分图片我们可以通过Graphic.DrawImage方法实现,而屏幕快照也可以使用Graphic.CopyFromScreen方法获取。那么问题就在于与用户的交互了,即如何在屏幕上画一个矩形区域,拖动矩形区域,修改矩形区域的尺寸。
这里我们的实现方式是,创建一个窗体,使其全屏显示,背景为屏幕快照,那么问题就成了在窗体上画矩形了。如果有这方面经验,则问题就方便解决了。
C#实现
这里的截图功能包括:Ctrl+Alt+A快捷键,截图保存,区域拖放,区域尺寸修改等功能。
ScreenOverlay.cs为上面说的窗体,其背景为屏幕快照,代码如下:public sealed class ScreenOverlay : Form {
public SelectionRectangle Selection;
private ContextMenuStrip selectedMenu;
private IContainer components = null;
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
public ScreenOverlay() {
this.components = new System.ComponentModel.Container();
this.selectedMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.selectedMenu.SuspendLayout();
this.SuspendLayout();
this.selectedMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
new ToolStripMenuItem("Save as"){ Tag = "save" },
new ToolStripMenuItem("Copy to Clipboard"){Tag = "copy"},
new ToolStripSeparator(),
new ToolStripMenuItem("Reset"){ Tag = "reset"},
new ToolStripMenuItem("Exit"){ Tag = "exit"}
});
this.selectedMenu.Size = new System.Drawing.Size(161, 98);
this.selectedMenu.Closed += new ToolStripDropDownClosedEventHandler
(this.selectedMenu_Closed);
this.selectedMenu.ItemClicked += new ToolStripItemClickedEventHandler
(this.selectedMenu_ItemClicked);
this.ShowInTaskbar = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.TopMost = true;
this.DoubleClick += new System.EventHandler(this.ScreenOverlay_DoubleClick);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ScreenOverlay_KeyDown);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ScreenOverlay_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ScreenOverlay_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ScreenOverlay_MouseUp);
this.selectedMenu.ResumeLayout(false);
this.ResumeLayout(false);
Rectangle rect = Screen.PrimaryScreen.Bounds;
Image bitmap = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(rect.Location, new Point(0, 0), rect.Size);
g.Dispose();
this.Location = rect.Location;
this.BackgroundImage = bitmap;
this.Size = rect.Size;
this.Selection = new SelectionRectangle(bitmap, rect);
}
private void ScreenOverlay_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == System.Windows.Forms.MouseButtons.Left) {
if (this.Selection.Status == SelectStatus.Unknow) {
this.Selection.StartTo(e.Location);
this.Selection.Status = SelectStatus.Selecting;