软件(也许应该叫做小程序)历史:
    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
    

解决方案 »

  1.   

    AnyView,AnyCall...之类的Any比较多啊另外,貌似一款手机阅读器也叫AnyView的,呵呵
      

  2.   

    哈哈,楼主的PhotoShop终于出炉了,顶一个
      

  3.   

    很牛很强大,真的想不到用VB写的一个几百K的程序竟然可以有如此强大的功能!
    简单测试了一下,有几个小问题供楼主参考:
    1、新建一个图像的时候,最好能像photoshop那样提示一下将生成文件的大小;
    2、执行滤镜操作时,所选择的选区不在预览窗口的中心;
    3、保存时貌似应该直接保存为原来的文件格式,而不是每次都要重新选择文件类型;
    4、保存时就算选择了取消,文件菜单的保存也会变为不可用;
    5、关于窗口的问题跑得太快了好几遍都没看清内容,也许是我的CPU太快了?
    6、工具箱、缩略图、图层等各个工具栏能否加个“自动停靠”效果;
    7、现在好像还不支持任何热键,比如建立椭圆选区时我试了shift、ctrl、alt等键都不能帮我实现正圆选区;

    已有的功能已经跟photoshop很接近了,尤其是建立自由选区和多边形选区的时候总保持封闭选区这一特色,个人感觉比photoshop还要人性化,呵呵。
      

  4.   

    调整图层透明度确实没有效果,点一下某个图层后透明度值自动回到100了,而且当把上面图层选择Disslove时,随便在画布内点一下,图层相叠加的部分图像都会变化,这也应该是一处bug
      

  5.   

    1、新建一个图像的时候,最好能像photoshop那样提示一下将生成文件的大小; 这个简单 ,可以搞定。2、执行滤镜操作时,所选择的选区不在预览窗口的中心; 
    这个也不难3、保存时貌似应该直接保存为原来的文件格式,而不是每次都要重新选择文件类型; 
    这个得说下了,因为我在读取的时候把所有的数据都转换为32位位图的数据了,而不管原来是1\4\8\16\24位的,这样坐主要是为了显示方便的原因,所以我的菜单中没有模式菜单的。这样就丢失了原先的一些信息,所以保存的时候就比较麻烦,我现在的保存功能只是按照我预先设计的参数保存的。这是没有办法的事情。4、保存时就算选择了取消,文件菜单的保存也会变为不可用; 
    这是个BUG,容易修正5、关于窗口的问题跑得太快了好几遍都没看清内容,也许是我的CPU太快了? 
    这个不知道你什么意思,你是指窗口菜单?6、工具箱、缩略图、图层等各个工具栏能否加个“自动停靠”效果; 
    还在完善中,其实我是把有几个工具栏给隐藏了,因为还不完善。7、现在好像还不支持任何热键,比如建立椭圆选区时我试了shift、ctrl、alt等键都不能帮我实现正圆选区; 
     是还没有坐热键,要实现正圆,可以用风格里的固定比例。
    一、调色器的位置有点问题。 
    '发现了 
    二、色层透明好像没有效果。 
    晕,居然那个timer的Enabled设置为False了。三、界面有闪烁现象,偶尔自绘菜单还会出现来不及刷新的现象。 这个菜单是网络上HOOKMENu,我没有研究他的代码四、没有撤消功能。 
    撤销功能的实现比较复杂,我目前没有完全搞定,因为有选区和数据、位置等不同类型的撤销。
    五、光标没有随着功能改变发生变化。 

    ’光标鼠标形状的改变没有坐
    六、程序有时不稳定,在1个小时内出现了两次问题,一是在垂直翻转时出现,一是在填充色层时出现,很奇怪,这几个操作我又试了好几次,却不再出现。 不稳定是因为访问了非法内存,模拟指针没办法,如果用数组的话可以还有个溢出提示,模拟指针就会直接崩溃。
      

  6.   


    选区描边的那个选项框。选取了颜色以后颜色标签后面的那个颜色框一直是淡绿色。没有变成自定义的颜色但是点确定以后描边的颜色确实是我选的自定义颜色。算不算BUG?
      

  7.   

    看了一下,有点Photoshop的感觉,但是确实是业余做来玩玩的,很多功能和概念都没有,呵呵。
    还有发现楼主的Lab色彩没模仿搞出来,不知道楼主研究过吗?
    我这段时间也在写一个类,概念也是模仿Photoshop的,
    我在色彩系统上,Lab的运算没搞出来,不知楼主对这方面了解吗,能否赐教一下。
      

  8.   

    Lab网上有现成的计算公式 自己只需要适当优化吧
      

  9.   

    谢谢systemx 

    描边的哪个是少了个更新的语句。
    新建图层 矩形选区 执行填充操作——》程序崩溃(试了五次。没有例外情况)这个也找到错误的原因了
    新建空白文档 划出一个矩形选区 选择一种前景色 编辑—》填充-》确定 不管前景色选择的是哪一种。填充出来的都是白色 一个粗心的错误"关于"里面的那首音乐貌似非常耳熟呀.......
    这个就是VB彩蛋的哪个音乐。
      

  10.   

    打开文件有个问题,在打开窗口中,找到(一层层文件夹找)C:\Documents and Settings\Administrator\桌面\xxx.gif,打不开程序死掉.直接在下拉里面选"桌面"可以打开xxx.gif
      

  11.   

    打开文件有个问题,在打开窗口中,找到(一层层文件夹找)C:\Documents and Settings\Administrator\桌面\xxx.gif,打不开程序死掉.直接在下拉里面选"桌面"可以打开xxx.gif
    看了一下,确实存在这个问题,但是程序没有死掉,你在等一下他还是可以代开,目前没有找到原因,因为在IDE下运行他也是这样,没有出现错误,就是慢, 这个打开对话框我是用的系统的API的,还不清楚是什么地方造成慢的。谢谢。
      

  12.   

    使用放大镜工具的时候,最好加上图标,
    然后按住shift之类的按键可以切换放大/缩小模式
      

  13.   

    啊。啊。昨天想继续发。CSDN说偶灌水偶汗昨天还发现一个问题。就是不管是新建文件是打开文件进行修改操作以后再关闭程序好像都没有提示保存上面有个兄弟提到了保存对话框。但是我这没有偶用的系统是WIN2003 SERVER SP1 不知道跟系统有没有关系
      

  14.   

    与系统无关
    没有加入判断语句,也就是说没有写提示的代码。Thanks again.
      

  15.   

    LZ,我下载解压缩后,双击,报错.
    Run-time error '53':
    File not found: gdiplus
      

  16.   

    我前面已经说过了,需要gdiplus的支持。
      

  17.   


    Jay36 终于来了,我看和你的那个差不多。都是牛人!
      

  18.   

    1、就是没有系统“撤消功能”、“恢复功能”,以及百分比量度尺(图像大小百分比)。 撤销 恢复在进行中,百分尺 有想法。
    2、另外工具条还少了点。 工具条少了点,这不时第一个版本吗,要为以后扩展考虑3、再就是,双击“标题拦”,你的几个子窗口都跑到主动窗口外面去了。
    似乎Photoshop也是的
      

  19.   

    我觉得PhotoCap这个做的不错,不过是用delphi写的,功能堪比photoshop
      

  20.   

    我的更接近光影魔术手(别扔臭鸡蛋,虽然相比差很多)
    楼主的更接近PS。但是我的界面还是参考PS很多的 比如右侧工具栏就是取自PS CS3
      

  21.   

    我看了一下,这个软件不小,应该有2至3M,只不过用UPX压缩了一下,速度还不错。
      

  22.   

    AnyView名字還可以,幫你測試一下.
      

  23.   

    兄弟,这里标尺的代码,,,你看看你用的上去不,,
    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
      

  24.   


    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
    以前我用过这个代码,,也是网上找的,,
      

  25.   

    你好,请与我联系,我公司需写一个类似Photoshop的软件