软件(也许应该叫做小程序)历史:
2004年,大四毕业设计,题目是《基于火焰图像处理的回转窑温度场的提取》,初次接触图像处理,在半年的时间内,徘徊在图像处理的边缘而不得正果,答辩上的事情反正就那样过去的。读研后,鉴于对本专业毫无兴趣(保送的,也就没有想换专业了),又没有女人垂青,大好时光匆匆过了一段,觉得人生苦短,不能就此虚度。鉴于有过图像开发的历史,发现自己对这方面还是有些许感冒,就开始了图像编程的深入。
2005年开始,导师的一个项目正好也于图像处理有关,作为曾经有过这方面经验的学生,我肯定作为导师的首选棋子。也好,有点事情做,比大部分研究生在校荒废三年总要好。这个项目对实时性要求较强,开发语言甲方没有制定,我们自己选择了VB6.0。网络上到处都充满了对VB图像处理的批判,自己是个不信邪的人,虽然那时候接触编程语言只有1年,不过自己相信能把这问题解决,正好那个时候看到ZYL910大侠的VB高速图像处理系列文章。半年后,项目得以顺利完成,其中采用的方法是普通的GetDibits。
项目做完后,2006年,研二了,没有课程,没有坐什么项目了,天天坐在实验室里,很无聊,我就学了下PhotoShop,Sql sever,AutoCad,Premior等等,不过都是泛泛的看看。基本上这个时候电脑就是我老婆了,说实在的,读研期间还没有女朋友或者说之前没有过女朋友的人应该不多的,我们宿舍居然就有2个,想想自己硬件一般般,心里也还比较平衡。大概是下半年,偶尔翻翻ZYL910的那篇文章,对其中的模拟指针突然非常感兴趣,于是摸索了好久也对其有了相当的了解(发现自己还不是太笨)。这时候就把以前写过的一些图像代码重新写了下,速度上的大幅提升让我对VB的信心大增,恰巧那时在网络上看到Paint.net这个开源的C#软件,其中的滤镜及其丰富,效果也相当完美。后来就化了相当的力气把这些代码的大部分改成VB,经过一年多的努力,于是就有了我在VBGOOD上发布的Cimage.dll。
2007年毕业后,找了一家国企的设计院工作,工作强度比较低,当然待遇也一般般,不过我很容易满足,并且在一个地方安顿下来就不想动,说实在的对这份工作还是比较满意的,虽然我并不热爱他。好像有人说过当兴趣变为职业时,人是痛苦的吧。工作之余,还是把编程作为自己的第二任务,第一任务哈哈是追美眉。这时,Cimage.dll基本停止了开发,因为用VB写的图像处理的DLL和VC相比即使速度不相差多少也是没有什么优势的。恰巧在VBGOOD上Jay36发表了他用VB写的一个图像处理程序Jsee,激起了我也写个完整的程序的想法,模仿的目标是曾经学习过的PhotoShop大牛。一开始在2007年底之前采用的是DLL和EXE分开开发,并且是单文档的,并且不涉及到图层。这个过程大概前后开发了半年,没有一个像样的作品出来。2008年年初,在PSC上看到了几个比较优秀的图像处理代码,结合我自己的开发经验,对开发一个带图层多文档程序有了想法,并且决定抛弃EXE和DLL分开写的方式而改为单EXE文件,期间,我建立了一个自己的QQ图像处理群,也认识了一些志同道合的朋友。一晃又快要到年底了,多重考虑后,决定暂时放弃一些功能的编写,而先给出一个大的框架,以后在慢慢完善,于是有了这个版本的发布。 软件功能和特色:
1、支持BMP、jpg、gif、png、wmf、tiff、emf、pcx、psd、tga、ico、pbt等格式的读取,其中TIFF,ICO和GIF图像如果含有多帧,可以制定要读取的帧数
2、支持保存为BMP、JPG、GIF、PNG、TIFF、TGA、ICO、PBT、wmf、emf等格式,其中PBT格式为自定义格式,可以保存图层的相关信息。不过有些格式的支持不完美。
3、支持图层处理,课设置图层混合方式及透明度等等。
4、支持选区处理,选区合并方式及选区工具和PS类似。
5、支持命令行及OLE操作。
6、拥有多种滤镜特效。
7、启动速度和占用内存量较为合理。
8、文件大小不到1MB,在内部调用了GDIPLUS.DLL,如果操作系统为98以上及系统中包含了GDIPLUS.DLL,则可绿色执行。
9、除一些特殊的滤镜外,还加入了一些在分析上常用的工具,比如QQ截屏、FFT变换等。
10、和Panit.net相比执行速度有一定优势,和PS相比,调整中的滤镜速度差不多。
当然,因为时间比较仓促,这次发布程序一定存在很多Bug和错误,希望大家如果感兴趣并且有时间的话能够帮忙测试,我将在致谢名单上加入您的名字。下载地址 :http://d.download.csdn.net/down/722477/laviewpbt
解决方案 »
- 合并单元格的问题
- 如何在DataReport中实现横向打印,和横向预览。
- 读取二进制文件
- 如何用VB设计VCD播放器阿?
- 用RICHED20.DLL开发语法加亮编辑器的朋友请进(此文档长期有效)?
- 如何实现点击一张图片,使程序退出
- SQL Server数据库没有保留精度的功能吗?
- 问如何将现有连接到access的数据库改到连接到sql数据库
- 为什么我的VB6中没有fso??????????????????????????????????????????
- 求教:VB5不能用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- 求助XceedZip控件的使用方法
- VB的Form.ControlBox 问题,请大家帮帮忙
简单测试了一下,有几个小问题供楼主参考:
1、新建一个图像的时候,最好能像photoshop那样提示一下将生成文件的大小;
2、执行滤镜操作时,所选择的选区不在预览窗口的中心;
3、保存时貌似应该直接保存为原来的文件格式,而不是每次都要重新选择文件类型;
4、保存时就算选择了取消,文件菜单的保存也会变为不可用;
5、关于窗口的问题跑得太快了好几遍都没看清内容,也许是我的CPU太快了?
6、工具箱、缩略图、图层等各个工具栏能否加个“自动停靠”效果;
7、现在好像还不支持任何热键,比如建立椭圆选区时我试了shift、ctrl、alt等键都不能帮我实现正圆选区;
已有的功能已经跟photoshop很接近了,尤其是建立自由选区和多边形选区的时候总保持封闭选区这一特色,个人感觉比photoshop还要人性化,呵呵。
这个也不难3、保存时貌似应该直接保存为原来的文件格式,而不是每次都要重新选择文件类型;
这个得说下了,因为我在读取的时候把所有的数据都转换为32位位图的数据了,而不管原来是1\4\8\16\24位的,这样坐主要是为了显示方便的原因,所以我的菜单中没有模式菜单的。这样就丢失了原先的一些信息,所以保存的时候就比较麻烦,我现在的保存功能只是按照我预先设计的参数保存的。这是没有办法的事情。4、保存时就算选择了取消,文件菜单的保存也会变为不可用;
这是个BUG,容易修正5、关于窗口的问题跑得太快了好几遍都没看清内容,也许是我的CPU太快了?
这个不知道你什么意思,你是指窗口菜单?6、工具箱、缩略图、图层等各个工具栏能否加个“自动停靠”效果;
还在完善中,其实我是把有几个工具栏给隐藏了,因为还不完善。7、现在好像还不支持任何热键,比如建立椭圆选区时我试了shift、ctrl、alt等键都不能帮我实现正圆选区;
是还没有坐热键,要实现正圆,可以用风格里的固定比例。
一、调色器的位置有点问题。
'发现了
二、色层透明好像没有效果。
晕,居然那个timer的Enabled设置为False了。三、界面有闪烁现象,偶尔自绘菜单还会出现来不及刷新的现象。 这个菜单是网络上HOOKMENu,我没有研究他的代码四、没有撤消功能。
撤销功能的实现比较复杂,我目前没有完全搞定,因为有选区和数据、位置等不同类型的撤销。
五、光标没有随着功能改变发生变化。
’光标鼠标形状的改变没有坐六、程序有时不稳定,在1个小时内出现了两次问题,一是在垂直翻转时出现,一是在填充色层时出现,很奇怪,这几个操作我又试了好几次,却不再出现。 不稳定是因为访问了非法内存,模拟指针没办法,如果用数组的话可以还有个溢出提示,模拟指针就会直接崩溃。
选区描边的那个选项框。选取了颜色以后颜色标签后面的那个颜色框一直是淡绿色。没有变成自定义的颜色但是点确定以后描边的颜色确实是我选的自定义颜色。算不算BUG?
还有发现楼主的Lab色彩没模仿搞出来,不知道楼主研究过吗?
我这段时间也在写一个类,概念也是模仿Photoshop的,
我在色彩系统上,Lab的运算没搞出来,不知楼主对这方面了解吗,能否赐教一下。
描边的哪个是少了个更新的语句。新建图层 矩形选区 执行填充操作——》程序崩溃(试了五次。没有例外情况)这个也找到错误的原因了
新建空白文档 划出一个矩形选区 选择一种前景色 编辑—》填充-》确定 不管前景色选择的是哪一种。填充出来的都是白色 一个粗心的错误"关于"里面的那首音乐貌似非常耳熟呀.......
这个就是VB彩蛋的哪个音乐。
看了一下,确实存在这个问题,但是程序没有死掉,你在等一下他还是可以代开,目前没有找到原因,因为在IDE下运行他也是这样,没有出现错误,就是慢, 这个打开对话框我是用的系统的API的,还不清楚是什么地方造成慢的。谢谢。
然后按住shift之类的按键可以切换放大/缩小模式
没有加入判断语句,也就是说没有写提示的代码。Thanks again.
Run-time error '53':
File not found: gdiplus
Jay36 终于来了,我看和你的那个差不多。都是牛人!
2、另外工具条还少了点。 工具条少了点,这不时第一个版本吗,要为以后扩展考虑3、再就是,双击“标题拦”,你的几个子窗口都跑到主动窗口外面去了。
似乎Photoshop也是的
楼主的更接近PS。但是我的界面还是参考PS很多的 比如右侧工具栏就是取自PS CS3
Option Explicit
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function ShowCursor Lib "user32" (ByVal bShow As Long) As LongPrivate Declare Function Polygon Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
Private Pt2() As POINTAPIPrivate Declare Function RoundRect Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As LongPrivate Enum WHERE_IS
Inside = 0
Outside = 1
OnBorder = 2
OnVertex = 3
DontExist = 4
End EnumPrivate CX As Single
Private CY As Single
Private RADIUS As Single
Private ASPECT As SinglePrivate PI As Double
Private HALPH_PI As DoublePrivate Function InsidePolygon(PtApi() As POINTAPI, ByVal X As Single, ByVal Y As Single) As WHERE_IS
Dim i As Integer
Dim theta As Double
Dim alfa As Double
Dim xNew As Double
Dim yNew As Double
Dim angle As Double
Dim nCount As Integer nCount = UBound(PtApi)
If (nCount < 3) Then
InsidePolygon = DontExist
Exit Function
End If For i = 0 To nCount
If (CLng(X) = PtApi(i).X And CLng(Y) = PtApi(i).Y) Then
InsidePolygon = OnVertex
Exit Function
End If
Next i PtApi(nCount).X = PtApi(0).X
PtApi(nCount).Y = PtApi(0).Y
angle = 0
For i = 0 To nCount - 1
theta = ATan2(CDbl(PtApi(i).X) - X, CDbl(PtApi(i).Y) - Y)
xNew = (CDbl(PtApi(i + 1).X) - X) * Cos(theta) + (CDbl(PtApi(i + 1).Y) - Y) * Sin(theta)
yNew = (CDbl(PtApi(i + 1).Y) - Y) * Cos(theta) - (CDbl(PtApi(i + 1).X) - X) * Sin(theta)
alfa = ATan2(xNew, yNew)
If Round(alfa, 1) = Round(PI, 1) Then
InsidePolygon = OnBorder
Exit Function
End If
angle = angle + alfa
Next i
If (Abs(angle) < 0.0001) Then
InsidePolygon = Outside
Exit Function
ElseIf (Abs(angle) > PI) Then
InsidePolygon = Inside
Exit Function
End IfEnd FunctionPrivate Function ATan2(ByVal X As Double, ByVal Y As Double) As Single If X = 0 Then
If Y > 0 Then
ATan2 = HALPH_PI
ElseIf Y < 0 Then
ATan2 = -HALPH_PI
Else
ATan2 = 0
End If
ElseIf Y = 0 Then
If X < 0 Then
ATan2 = PI
Else
ATan2 = 0
End If
Else
If X < 0 Then
If Y > 0 Then
ATan2 = Atn(Y / X) + PI
Else
ATan2 = Atn(Y / X) - PI
End If
Else
ATan2 = Atn(Y / X)
End If
End If
End FunctionPrivate Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyF8 And Shift = 0 Then
While ShowCursor(False) >= 0
Wend
ElseIf KeyCode = vbKeyF9 And Shift = 0 Then
While ShowCursor(True) < 0
Wend
End If
End SubPrivate Sub Form_Load()
Dim Pt As POINTAPI
PI = 4 * Atn(1)
HALPH_PI = PI / 2
Show
DoEvents
Pt.X = PixToMM(CX)
Pt.Y = PixToMM(CY)
ClientToScreen hwnd, Pt
SetCursorPos Pt.X, Pt.Y
End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim WI As WHERE_IS
Dim sPos As String
Dim sCaption As String AutoRedraw = False
DrawWidth = 1
Refresh
DrawStyle = vbDot
If X >= 5 And Y >= 5 Then
Line (X, 0)-(X, ScaleHeight)
Line (0, Y)-(ScaleWidth, Y)
sPos = "X:" + Str(Round(X - 5, 2)) + ", Y:" + Str(Round(Y - 5, 2))
CurrentX = ScaleWidth - (TextWidth(sPos) + 1)
CurrentY = ScaleHeight - (TextHeight(sPos) + 1)
Print sPos
End If
WI = InsideEllipse(X, Y)
If WI = Inside Then
If sCaption <> "InSide Ellipse" Then
sCaption = "InSide Ellipse"
End If
ElseIf WI = Outside Then
If sCaption <> "OutSide Ellipse" Then
sCaption = "OutSide Ellipse"
End If
Else
If sCaption <> "OnBorder Ellipse" Then
sCaption = "OnBorder Ellipse"
End If
End If
WI = InsidePolygon(Pt2(), PixToMM(X), PixToMM(Y))
If WI = Inside Then
If sCaption <> sCaption + " and InSide Polygon" Then
sCaption = sCaption + " and InSide Polygon"
End If
ElseIf WI = Outside Then
If sCaption <> sCaption + " and OutSide Polygon" Then
sCaption = sCaption + " and OutSide Polygon"
End If
ElseIf WI = OnBorder Then
If sCaption <> sCaption + " and OnBorder Polygon" Then
sCaption = sCaption + " and OnBorder Polygon"
End If
ElseIf WI = OnVertex Then
If sCaption <> sCaption + " and OnVertex Polygon" Then
sCaption = sCaption + " and OnVertex Polygon"
End If
Else
If sCaption <> sCaption + " and Polygon Don't Exist" Then
sCaption = sCaption + " and Polygon Don't Exist"
End If
End If
If Me.Caption <> sCaption Then
Me.Caption = sCaption
End If
End Sub
Private Sub Form_Resize()
On Error Resume Next
If Me.WindowState <> vbMinimized Then
CX = (ScaleWidth / 2) + 3
CY = (ScaleHeight / 2) + 3
RADIUS = (ScaleHeight / 3)
ASPECT = 1.2
DrawStyle = vbSolid
AutoRedraw = True
Cls
DrawWidth = 1
DrawMeterGuide
DrawWidth = PixToMM(1)
DrawRhomb
ForeColor = QBColor(2)
ForeColor = QBColor(0)
Refresh
End If
End SubPrivate Sub Form_Unload(Cancel As Integer)
ShowCursor True
Cls
Erase Pt2
End
Set Form1 = Nothing
End Sub
Private Function InsideEllipse(ByVal X As Single, ByVal Y As Single) As WHERE_IS
Dim TBase As Single
Dim THeight As Single
Dim THypotenuse As Single
If ASPECT = 1 Then
TBase = Abs(CX - X)
THeight = Abs(CY - Y)
ElseIf ASPECT > 1 Then
TBase = Abs(CX - X) * ASPECT
THeight = Abs(CY - Y)
Else
TBase = Abs(CX - X)
THeight = Abs(CY - Y) / ASPECT
End If
THypotenuse = CSng(Sqr(TBase ^ 2 + THeight ^ 2))
If THypotenuse < RADIUS - CSng(1 / PixToMM(1)) Then
InsideEllipse = Inside
ElseIf THypotenuse > RADIUS + CSng(1 / PixToMM(1)) Then
InsideEllipse = Outside
Else
InsideEllipse = OnBorder
End If
End FunctionPrivate Sub DrawMeterGuide()
Dim X As Single
Dim Y As Single
Dim iC As Integer Line (0, 0)-(5, 5), QBColor(7), BF
CurrentX = 0.2
CurrentY = 0.5
Print "mm"
For X = 0 To ScaleWidth Step 1
If X Mod 10 = 0 Then
Line (X + 5, 0)-(X + 5, 5)
If iC > 0 Then
CurrentX = (X + 5) - CSng(TextWidth(CStr(iC)) / Len(CStr(iC)) + IIf(Len(CStr(iC)) = 1, 0, 1))
CurrentY = 5
Print iC
End If
iC = iC + 1
Else
Line (X + 5, 0)-(X + 5, IIf(X Mod 5 = 0, 3, 1))
End If
Next X
iC = 0
For Y = 0 To ScaleHeight Step 1
If Y Mod 10 = 0 Then
Line (0, Y + 5)-(5, Y + 5)
If iC > 0 Then
CurrentX = 5
CurrentY = (Y + 5) - CSng(TextHeight(CStr(iC)) / 2)
Print iC
End If
iC = iC + 1
Else
Line (0, Y + 5)-(IIf(Y Mod 5 = 0, 3, 1), Y + 5)
End If
Next Y
End SubPrivate Function PixToMM(ByVal Pix As Single) As Single
PixToMM = Pix * 3.78
End FunctionPrivate Sub DrawRhomb() ReDim Preserve Pt2(0 To 4)
Pt2(0).X = PixToMM(CX)
Pt2(0).Y = PixToMM(CY) - IIf(ASPECT <= 1, PixToMM(RADIUS * ASPECT), PixToMM(RADIUS / ASPECT))
Pt2(1).X = PixToMM(CX) + IIf(ASPECT <= 1, PixToMM(RADIUS * ASPECT), PixToMM(RADIUS / ASPECT))
Pt2(1).Y = PixToMM(CY)
Pt2(2).X = PixToMM(CX)
Pt2(2).Y = PixToMM(CY) + IIf(ASPECT <= 1, PixToMM(RADIUS * ASPECT), PixToMM(RADIUS / ASPECT))
Pt2(3).X = PixToMM(CX) - IIf(ASPECT <= 1, PixToMM(RADIUS * ASPECT), PixToMM(RADIUS / ASPECT))
Pt2(3).Y = PixToMM(CY)
Pt2(4) = Pt2(0)
' Polygon hdc, Pt2(0), 5
End Sub
以前我用过这个代码,,也是网上找的,,