C#开发鹰眼浏览工具-转

以开发一个图像处理软件为例,我们使用 C# 语言,涉及到对图像的读取保存,鹰眼截取,效果设置,放大缩小等简单操作。其中鹰眼浏览是需要重点自学的部分。

    如果是以项目为驱动,为了完成项目来自我学习,可以从以下入手:
    1. 学习图像知识,开发不是要求我们达到图形学博士的水平,只要利用现有的技术就可以完成的,
       只需要我们了解图像内部的结构。鉴于是学习理论知识,于是我们可以选取图形学方面的书的
       相关章节来阅读。
    2. 学习C#中的GDI+库,因为它包含了图形图像的大部分操作方法。鉴于是学习实用方法,我们可
       以从网络上查找相关文档或者案例。

    下面以鹰眼效果为例讲解实现的过程和细节:

   
    所谓鹰眼,通俗的讲就是小地图,玩过星际争霸的都知道,它的主界面左下角就是小地图,它的主要功能是让人瞥上一眼就能大体了解整个的战场的地形和敌我力量分布,而且能利用小地图在整个战场上快速的移动视角,因此在很多游戏中鹰眼的作用很大。在 GUI程序中,鹰眼也是类似的作用。它能显示全部文档的大概的结构,而且能利用它来快速的在文档中移动视角。很多商业的GUI程序,特别是设计器类的程序,都提供了鹰眼功能。

    鹰眼的结构一般是在一个显示区域的中间,显示了整个文档的缩小的视图,一般的为了性能,采用整个文档的缩小的预览图片来显示。然后在这个小视图上使用一个方框或者其他手段来突出显示其中的一部分,而这一部分代表了当前主视图区域在整个文档中的位置和大小。当主视图区域进行滚动时,鹰眼中突出显示的区域也会移动。当用户用鼠标在鹰眼区域中点击或拖拽方式改变突出显示区域的位置时,主视图区也会做相应的滚动。当整个文档的内容发生大的改变时,鹰眼中文档预览BMP图片也会更新。 

现在说说实现鹰眼的过程:

首先准备文档预览BMP图片,该图片要求大小合适,不能过大或过小。根据鹰眼区域的大小和整个文档从长宽比获得合适的图片大小,算出缩小比例,这个比例很重要,需要妥善保存。然后创建一个Bitmap 对象,再使用 System.Drawing.Graphics.FromImage 创建一个Graphics 对象,调用 Graphics.ScaleTransfrom 来设置缩小比例,然后使用个Graphics绘制整个文档内容,绘制过程和正常在视图区域中绘制没什么区别。为了提高性能,当缩小比例很小时,有些比较小的文档元素不必绘出,也不必绘制文本,此时需要靠缩小比例来进行判断了。

    当用户改变的文档内容时,应该考虑更新鹰眼的预览BMP图片了,当改变量相对于整个文档来说不大时,不必更新,若改变量比较大时需要更新预览BMP图片了,为了提高性能,每一次改变文档时都将改变区域的面积和整个文档的面积进行比较,若两者比率超过某个设定的值时,就进行更新,否则不必更新。

    获得预览BMP图片后,将其放置在鹰眼区域的中间。然后根据主视图区域的大小( Control.ClientSize )和预览图片的缩小率获得其在鹰眼中的映射区域的大小,根据主视图区域在整个文档中的位置获得其映射位置在预览图片中的位置,如此就可确定主视图区域在预览图片中的映射区域的位置和大小,每次重绘鹰眼区域时就可以突出显示映射区域了。主视图区域每次进行滚动后都需要重新计算映射区域的位置并立即重绘鹰眼区域。若仅简单的使用Control.Invalidate声明鹰眼区域无效时会导致更新不及时,影响效果。由于鹰眼区域不大,绘制操作简单,在此可以简单的使用Control.Refresh进行全部绘制。

    切图的关键的代码如下:

    //从完整小地图对象be中锁住需要截取尺寸中的数据
   
System.Drawing.Imaging.BitmapData bmpData = be.LockBits(
                   actualsize,
                   System.Drawing.Imaging.ImageLockMode.ReadWrite,
                   System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
    IntPtr iPtr = bmpData.Scan0;//设置新的大地图的指针
    //得到新的大地图尺寸
    byte[] pixelvalue = new byte[(int)(10 * sizescale1 * 10 * sizescale2)];
    //获取切出的图的矩阵数组,将数据拷贝到新大地图的指针中
    System.Runtime.InteropServices.Marshal.Copy(
                   iPtr,
                   pixelvalue,
                   0, 
                   (int)(10 * sizescale1 * 10 * sizescale2));
问题可以得到解决,而且还学习了图形学方面的知识,所以我们发现自我学习通常由实际工作需要触发。如果是整套体系都要学习,那计划性就很重要,如果只为解决一个小问题,则可以跳过某些章节直入主题。如果没有实际工作需要而产生的学习需求通常处于兴趣,此时更加需要坚持,因为一时不能达到自己要的效果会打击自己的兴趣。
北大青鸟-中博 www.njaccp.com

转载于:https://www.cnblogs.com/TitanNJ/archive/2009/05/26/1489324.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值