WinForm下屏幕截图程序的实现
截图程序的代码参考了一个印度人的博客还有周银辉的博客, 这两位都是用WPF做的, 在截图的时候半透明遮罩都是用的WPF里的Canvas, 但WinForm里没有这个控件, 我想出了另一个办法.
大致思路是按截图按钮后, 打开另一个Form, 这个Form没有边框, 初始就是最大化占满整个屏幕, 背景色为白色, 透明度为50%. 这样就差不多是个半透明遮罩的效果了, 在任务栏显示图标这个属性也要设为false, 大概这样大家就明白我的意思了. 而在截取屏幕部分图像时, 这部分的半透明色彩要恢复成屏幕这部分的真面目, 所以我想了一个办法, 把这个窗口的TransParencyKey设为CornflowerBlue, 然后在屏幕上画CornflowerBlue这个颜色的矩形框, 这样就可以把这个框框部位的颜色变成屏幕的颜色了. 效果如下图:
那个矩形框是这样绘制出来的:
private void Form2_MouseDown(object sender, MouseEventArgs e) { x = MousePosition.X; y = MousePosition.Y; isMouthDown = true; } private void Form2_MouseMove(object sender, MouseEventArgs e) { if (isMouthDown) { width = Math.Abs(MousePosition.X - x); height = Math.Abs(MousePosition.Y - y); g = CreateGraphics(); g.Clear(BackColor); g.FillRectangle(Brushes.CornflowerBlue, x<MousePosition.X?x:MousePosition.X, y<MousePosition.Y?y:MousePosition.Y, width + 1, height + 1); } } private void Form2_MouseUp(object sender, MouseEventArgs e) { nowX = MousePosition.X + 1; nowY = MousePosition.Y + 1; this.Close(); formMain.pcurrentWin.Snap(x < nowX ? x : nowX, y < nowY ? y : nowY, Math.Abs(nowX - x), Math.Abs(nowY - y));//开始截图 formMain.pcurrentWin.Show(); }
周博客里提到的用这样的绘图方式在单显示器里效果还行, 双显示器里有明显的滞后感...我没有双显示器的环境, 希望有心人帮我测试一下在双显示器里画这个框框有没有滞后感. 但实际上在我电脑上运行的时候, 当鼠标移动重绘这个矩形时, 尽管没有所谓的滞后感, 但还是比较耗CPU的. 不知道Windows7桌面上的半透明蓝色矩形框是用什么技巧画出来的?
另外我发现了这两个人写的CopyFromScreen貌似写的都有一点问题, 比如周是这样写的:
g.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);
我后来也是传进这几个参数的, 但发现截全屏的时候, 比如我的显示器是1280*800, 截到的却总是1279*799这么大, 并且如果在屏幕的左上角(0, 0)单击一下, 却是截取的整个屏幕! 所以我后来把这个矩形的长宽都加上了1, 于是正常了...但尚不清楚这是为何(特别是单击左上角接触整个屏幕这个情况).
程序界面(部分功能还未写):
程序下载: ScreenSnap.zip
代码下载: ScreenSnapCode.zip
作者:Create Chen
出处:http://technology.cnblogs.com
说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。