利用VB6.0开发简易版类似PhotoShop软件的初步探讨

 

示例工程:https://files.cnblogs.com/laviewpbt/ImageShop.rar

 

声明:1、如果你对VB语言有意见或者看不起他,依旧欢迎你评论,但请你不要用辱骂性的语言来评论。

         2、本文不考虑项目的商业上的可行性及必要性。

         3、本文不存在攻击其他语言的目的。

这个问题我想了好久了,从毕业设计做图像检测开始接触图像,到工作中业余时间研究图像,大概也有个四五年了,程序也从最开始的零星凑合到一个小小的完整版本,常常在走路或者睡觉前为了某个问题的解决方案而思索,也曾经一下子迷失而暂时丧失兴趣。虽然到目前为止,整个工程还在改进和完善中,但是我已迫不及待的想和大家探讨下各方面的可行性。

一、运行速度。

我想这是很多人对我这个想法提出首要反对的原因。很多人都曾经说过VB慢,VB很垃圾,当然即使是现在还是有不少人有这种认识和想法。我不会对此做评价,我仅从一下几个方面来分析下速度问题。

1VB本身的问题。 的确,在很多方面VB设计的有缺陷,虽然为了用户开发的方便,其封装了很多低层的操作,但使得我们在面对有些问题时难以下手,不过这些在图像处理上是很少体现的。图像中存在大量的算法,而这些算法常常涉及到像素值的计算,像素值是什么,一般都是用Byte类型变量表示的,VB即使再怎么差劲,对于这些整数的加减乘除运算的计算速度难道会比其他语言差很多吗,我不这样认为,VB的编译器没有那么傻瓜。

2、指针问题。VB没有显式的给我们提供指针,而图像计算中确常常和指针打交道。的确,这是C类语言的骄傲,VB为了安全,向用户屏蔽了指针,从而造成了速度在一定程度上的损失,可是,热爱VB的大侠们在很久前就寻放到了通往指针秘门的羊肠小道----模拟指针,因为是模拟,所以比C的效率稍微低了那么一点点,但不是传说中的50%甚至更少,因此,我认为这也不是个问题。

3、复杂性问题。图像编辑软件是很复杂的,VB能处理这么复杂的流程吗,这个东西在某一个层次上,用其他语言能实现的,我想VB也不会有什么难题的。

4、优化问题。其实在很多情况下,VB慢是因为程序没有做优化,比如没有利用恰当的数据类型,没有合适的利用中间数据,错误的运用运算符,可以查表的地方用了循环等等,根据我个人的经验,同样的算法,我优化后的和别人用其他工具优化后的执行结果不会有什么出入。

从以上4个方面来说,采用VB和采用其他语言应该来说没有什么大的区别。可行。

二、资源占用

1VB本身的问题。我们直接打开VB,然后什么也不做,直接编译,这个只有一个窗体而什么都不做的程序大概占用了4MB左右的内存,有人对此心怀怨恨,如果在10年前,这可能是令人不爽的事情,而如今,在这个内存如此贱卖的年代,你还会在意吗。

同时在VB程序的UI制作中,资源占用的大户主要是PictureBox控件,不过我们的程序中不会有很多地方会用到他,并且这个占用的内存和我们打开的图像及一些中间操作所需要的内存相比,所占的比例是比较小的。而后者是利用其他语言设计时同样不可避免的部分。

2、图层、选区、蒙版等。他们是资源占用大户,举个简单的例子,如果打开一个1024*768大小的彩色图像,并为其添加一个蒙版,则这三项所占用的内存约为(1024*768*3+1+1=3.75MB的内存,如果有多个层,则相应的内存占用量就比较客观了。而用户在编辑图像时,也可能打开了多个窗口,同时,在进行滤镜处理时,往往需要创建一个当前图像的备份,从而使得程序临时占用的内存量增加很多。

另外,对于每一个活动窗口,我们还需要一个输出显示的缓冲区,这个缓冲区的大小不会超过屏幕的分辨率,因此,并且始终是一个32位的DIB,因此,在最坏的情况下,他占用了4MB左右的内存。

3、历史记录。这个要看程序怎么设计,很多软件具有无限重撤销和恢复功能,我想这个他应该是把需要的数据备份到了硬盘,这样做的一个结果是经常读写硬盘,个人认为是个不太合理的设计,要知道一副稍微大点的JPG文件加载到内存后,即使你采用了一些无损压缩技术保存到硬盘,往往也有10MB左右,这种频繁的读写在这个硬盘数据重要性大于一切的时代,似乎显得有点苍白。而类似于PS这种软件都有一个最大的撤销步骤数,这样做的一个目的是为了速度考虑,一个方面是为了保护硬盘。因此,我认为在图像处理中,在这样一个时代背景下,历史记录功能还是得靠内存大哥来帮助的。如果最撤销步数为20,并且每次都是对整幅图像进行的处理,则1024*768大小的图像因撤销而占用的内存约为45MB,这是最坏的情况,实际中我们总会设计到一些小历史内存占用的的操作,比如移动图层,小选区内处理等。

如此说来,从速度和性能及用户的利益角度来考虑,历史记录也是内存占用的大户。这是图像处理软件的无奈。

三、用户操作舒适度问题。

1、多线程问题。多线程一直是VB无法处理好的难题。在PS中,当我们移动一个层时,会明显的感觉到界面有多个矩形小方块在变换,这其实是为了考虑到用户的舒适性而做的一个技巧,也是必须运用多线程才能比较方便实现的地方。因为鼠标的移动是个频繁的事件,如果每移动一次,程序就响应更新,CPU是无法承担如此重的负荷的,给用户的感觉就是有点卡。在VB中要实现此效果,有很大的难度,这是一大遗憾。在我自己的工程中,我也只是通过优化输出缓冲区中的混合速度而使得这个问题不是那么明显。

2、键鼠操作问题。键鼠操作可以说是反映一个软件优良的关键标准,在技术实现上,这个也有很多学问,不过这东西应该是语言无关的,所以VB在这里应该不会卡住。

3、界面问题。众所周之,VB开发界面是最快捷和优秀的,所以,界面开发也不是关键问题所在。不过我自己因为对这个不怎么在行,界面很普通。

四、技术实现上的一些问题

1、图层。图层可以说是图像处理软件的精华,关于图层的实现,我有写过一篇简单的文章来描述,可以参见http://blog.csdn.net/laviewpbt/archive/2009/05/02/4143881.aspx

2、蒙版。蒙版在两幅或多副图像的透明合成中具有很高的适用价值,蒙版,按照我的理解,实际上也是一副256色的灰度图像,其大小和当前图层一样,如果某点为255,则表示当前层改点的透明度为不变,如果某点的值为127,则表示当前层改点的输出透明度为实际透明度的一半。如果为0,则当前点完全不透明,直接显示下部那一层的颜色值。而蒙版数据我们只会在计算输出图像时用到,并且由于其是一副256色的灰度图像,因此滤镜以及调整菜单中的效果都可以对齐使用,这和PS的情形是一致的,在技术实现上没有难度。

3、选区。选区也是一个很重要的功能,在早期我的理解和实现中,选区是借用了Windowsregion对象,利用这个对象很容易实现选区的并、差、异或等,且GetRegionDataA函数可以返回选区的每个小矩形的坐标,这样就可以实现选区的像素处理。开源中比较著名的Paint.net软件似乎也是利用的这个对象。但是利用region对象很难实现选区的抗锯齿以及类似羽化这样的高级功能。实际上,完美的选区是一副和画布一样大小的灰度图,注意,这里是和画布一样大小,灰度中的白色表示完全选中,黑色表示没有选中,中间的其他值则表示了原始像素值和处理后的像素值的混合程度。比如如果原始点的红色分量是160,对应的选区位置处的灰度值是200,则执行反色后改点的颜色值是(160*(255-200)+255-160*200)、255=109。为了达到抗锯齿效果,需要借助于GDI+的相关函数,同时,实现羽化也较为简单,对选区的灰度图像进行高斯模糊就可以了。

4、调整菜单。调整菜单中的滤镜之所以放在一起,我认为是因为他们都是对单个像素点进行的处理,而不涉及到领域像素。这里面的算法有些可以自己推敲,复杂点的网络上也有很多对其原理进行解释的,而大部分开源软件中都有设计这方面的代码。把他们转换成VB对我来说不是难事。

5、滤镜菜单。滤镜是图像中最具有创意的东西,也是发挥个性最合适的地方。众多的开源软件中有着数以百计的滤镜特效,要充实这个菜单可以说是简单而又最能见效果的地方。Paint.netCximageGimpPhoxo等等都是这方面宝贵的资源。

6、支持的格式。VB自身能支持JPGBMPGIFICOWMFEMF格式,但是由于在某些方面支持不全面,除了WMFEMF外,还是采用GDI+读取,GDI+可支持PNGGIFBMPJPGTIFF等格式。对于ICO格式,因其格式相对简单,可以直接从文件读取。另外,PCXTGA的格式读取也不是难事,而PSD格式因其复杂性,现在还只可以读取其一层的图像。

当然,还有其他的很多方面要考虑,但是我觉得,即使利用这款已经有了10年历史的老工具,依旧还是能写出很多具有很高价值的软件的,VB不是生来就应该受到鄙视的。

附件中的工具还我是半年前的作品,有着很多很多的错误,新的作品还在完善中。

 

 

'******************************你的评论是我发表文章的极大动力**'**************************

'***************************欢迎和你讨论图像技术问题:QQ 33184777************************

 

 

 

posted on 2009-06-02 17:28  彭佳乐  阅读(4965)  评论(31编辑  收藏  举报

导航