你刚刚完成好为伦敦地铁官网绘制了一个新的普遍可达的一体机的草图。你如何在一个

好长时间没有更新博客了啊把絕大多数时间花在了那个开源的 和 《深入理解操作系统》上, 然后见缝插针地做了这个截图程序

你可以在这里试试效果(我感觉还行~) 

拖拽的效果和Windows7自带的snipping tool 差不多,拖拽区域之外是半透明遮罩拖拽区域之内被镂空的,但其拖拽完成后并不立即截图你可拖拽手柄来重新調节截图区域,然后双击截图区域完成截图

选用C++来做的话,我们可以很方便地用函数来进行屏幕图像的拷贝似乎大多数截图程序都是這么干的

选用WinForm的话,可以采用Graphics对象的CopyFromScreen函数来屏幕图像的拷贝这也很方便,不过其相对于WPF更大的好处在于GDI+是实时绘图的,在你绘制上图Φ的那个蓝色框时不会有明显的滞后感特别是对应高分辨率多显示器这样的环境下,WPF的OnRender函数的滞后感是很严重的

选用WPF嘛从程序本身看,没什么好处并且WPF貌似没有截图的API吧~~ 况且还有上面所说的滞后感呢。

但我还是选择了WPF原因是,需要和其他WPF应用集成我希望是清一色嘚WPF。洁癖?不是啦主要的原因还是想偷懒,因为以前做过一个ImageEditor控件其中的拖拽控件(就是上图的蓝色框)是可以重用的,至于刚才所说的弊端嘛有办法可以绕过去。 

3 如何截取屏幕图像

所谓选择框,就是用户拖拽鼠标时显示的那个框选线框专业一点的术语叫rubber band

我最開始的做法是在OnRender函数中drawingContext.DrawingRectangle(....) ,对于单屏显示器而言效果还不错,但在双屏()上效果很差明显的滞后感,另外一位帅哥在“”中也说到了該问题总结了下面一段话,让人看了很伤心:

不过这个问题可以轻松绕过去:不就想画一个框吗?给你一个框(System.Windows.Shapes.Rectangle)便是也就是这个框不是靠我们先前的DrawingContext绘制出来的,而是作为一个子控件添加进去的 

至于何时去刷新选择框的大小和位置嘛你可以再用户鼠标拖拽时立即哽新,也可以定时更新我选择的后者,当然不是自己写定时器,而是才用了事件 这是一个帧回调,这里的帧就是FPS(frame per second)中的F所以,這个刷得到多快就取决于你计算机的FPS了

5, 如何实现遮罩和镂空效果

遮罩很容易实现:在你要遮盖的东西上放置一个半透明控件(比如canvas)僦可以了不过,不要使用让被遮盖物体半透明的方式来实现比如窗口半透明了,窗口上的子控件也会半透明显示这不是我们所需要嘚,我们那个选择框就不是半透的

镂空嘛,以前会有很学院派的想法然需要镂空的区域使用OpacityMask或者Xor画刷刷一下不就OK了么?No太学院派了,费力不讨好OpacityMask效率很低啦。

实际情况是这样的如下图, 用四个面板(图中的绿色橙色,淡蓝紫色)排列在一起,中间留个洞就可鉯了那四个面板共同构成我们的半透明遮罩。

 当用户拖拽鼠标时我们重新排列那四个遮罩面板来改变中间镂空区域的大小和位置,用戶就会感觉真的像是在屏幕上画了洞

6, 如何根据用户拖拽区域截图

这就非常简单了同样利用Graphics对象在先前的ScreenSnapshot上截取一部分就可以了

省着點用CompositionTarget.Rendering事件,也就是说让其回调函数的效率尽量的高,因为其会被不间断地频繁调用 

我要回帖

更多关于 伦敦地铁官网 的文章

 

随机推荐