VB 位图类

VERSION  1.0   CLASS
BEGIN
  MultiUse 
= -1  'True
END
Attribute VB_Name 
= "cDIBSection"
Attribute VB_GlobalNameSpace 
= False
Attribute VB_Creatable 
= True
Attribute VB_PredeclaredId 
= False
Attribute VB_Exposed 
= False
Option Explicit
'Powered by barenx
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    lpvDest 
As Any, lpvSource As Any, ByVal cbCopy As Long)

Private Type SAFEARRAYBOUND
    cElements 
As Long
    lLbound 
As Long
End Type
Private Type SAFEARRAY2D
    cDims 
As Integer
    fFeatures 
As Integer
    cbElements 
As Long
    cLocks 
As Long
    pvData 
As Long
    Bounds(
0 To 1As SAFEARRAYBOUND
End Type
Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long

Private Type RGBQUAD
    rgbBlue 
As Byte
    rgbGreen 
As Byte
    rgbRed 
As Byte
    rgbReserved 
As Byte
End Type
Private Type BITMAPINFOHEADER '40 bytes
    biSize As Long
    biWidth 
As Long
    biHeight 
As Long
    biPlanes 
As Integer
    biBitCount 
As Integer
    biCompression 
As Long
    biSizeImage 
As Long
    biXPelsPerMeter 
As Long
    biYPelsPerMeter 
As Long
    biClrUsed 
As Long
    biClrImportant 
As Long
End Type
Private Type BITMAPINFO
    bmiHeader 
As BITMAPINFOHEADER
    bmiColors 
As RGBQUAD
End Type
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As LongAs Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As LongAs Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
' Note - this is not the declare in the API viewer - modify lplpVoid to be
'
 Byref so we get the pointer back:
Private Declare Function CreateDIBSection Lib "gdi32" _
    (
ByVal hdc As Long, _
    pBitmapInfo 
As BITMAPINFO, _
    
ByVal un As Long, _
    lplpVoid 
As Long, _
    
ByVal handle As Long, _
    
ByVal dw As LongAs Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As LongByVal x As LongByVal y As LongByVal nWidth As LongByVal nHeight As LongByVal hSrcDC As LongByVal xSrc As LongByVal ySrc As LongByVal dwRop As LongAs Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As LongByVal hObject As LongAs Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As LongAs Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As LongAs Long
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As LongByVal lpsz As StringByVal un1 As LongByVal n1 As LongByVal n2 As LongByVal un2 As LongAs Long
Private Const BI_RGB = 0&
Private Const BI_RLE4 = 2&
Private Const BI_RLE8 = 1&
Private Const DIB_RGB_COLORS = 0 '  color table in RGBs

Private Type BITMAP
    bmType 
As Long
    bmWidth 
As Long
    bmHeight 
As Long
    bmWidthBytes 
As Long
    bmPlanes 
As Integer
    bmBitsPixel 
As Integer
    bmBits 
As Long
End Type
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As LongByVal nCount As Long, lpObject As Any) As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As LongByVal nWidth As LongByVal nHeight As LongAs Long

' Clipboard functions:
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As LongAs Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat As LongByVal hMem As LongAs Long
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Const CF_BITMAP = 2
Private Const CF_DIB = 8

' Handle to the current DIBSection:
Private m_hDIb As Long
' Handle to the old bitmap in the DC, for clear up:
Private m_hBmpOld As Long
' Handle to the Device context holding the DIBSection:
Private m_hDC As Long
' Address of memory pointing to the DIBSection's bits:
Private m_lPtr As Long
' Type containing the Bitmap information:
Private m_tBI As BITMAPINFO

Public Function CopyToClipboard( _
        
Optional ByVal bAsDIB As Boolean = True _
    ) 
As Boolean
Dim lhDCDesktop As Long
Dim lHDC As Long
Dim lhBmpOld As Long
Dim hObj As Long
Dim lFmt As Long
Dim b() As Byte
Dim tBI As BITMAPINFO
Dim lPtr As Long
Dim hDibCopy As Long

    lhDCDesktop 
= GetDC(GetDesktopWindow())
    
If (lhDCDesktop <> 0Then
        lHDC 
= CreateCompatibleDC(lhDCDesktop)
        
If (lHDC <> 0Then
            
If (bAsDIB) Then
               
MsgBox "I don't know how to put a DIB on the clipboard! Copy as bitmap instead!!!"
                
' Create a duplicate DIBSection and copy
                ' to the clipboard:
                'LSet tBI = m_tBI
                'hDibCopy = CreateDIBSection( _
                '        lhDC, _
                '        m_tBI, _
                '        DIB_RGB_COLORS, _
                '        lPtr, _
                '        0, 0)
                'If (hDibCopy <> 0) Then
                '    lhBmpOld = SelectObject(lhDC, hObj)
                '    BitBlt lhDC, 0, 0, Width, Height, m_hDC, 0, 0, vbSrcCopy
                '    SelectObject lhDC, lhBmpOld
                '    lFmt = CF_DIB
                '
                '     '....
                                    
                
'Else
                '    hObj = 0
                'End If
            Else
                
' Create a compatible bitmap and copy to
                ' the clipboard:
                hObj = CreateCompatibleBitmap(lhDCDesktop, Width, Height)
                
If (hObj <> 0Then
                    lhBmpOld 
= SelectObject(lHDC, hObj)
                    PaintPicture lHDC
                    SelectObject lHDC, lhBmpOld
                    lFmt 
= CF_BITMAP
                    
' Now set the clipboard to the bitmap:
                    If (OpenClipboard(0<> 0Then
                        EmptyClipboard
                        
If (SetClipboardData(lFmt, hObj) <> 0Then
                            CopyToClipboard 
= True
                        
End If
                        CloseClipboard
                    
End If
                
End If
            
End If
            DeleteDC lHDC
        
End If
        DeleteDC lhDCDesktop
    
End If
End Function


Public Function CreateDIB( _
        
ByVal lHDC As Long, _
        
ByVal lWidth As Long, _
        
ByVal lHeight As Long, _
        
ByRef hDib As Long _
    ) 
As Boolean
    
With m_tBI.bmiHeader
        .biSize 
= Len(m_tBI.bmiHeader)
        .biWidth 
= lWidth
        .biHeight 
= lHeight
        .biPlanes 
= 1
        .biBitCount 
= 24
        .biCompression 
= BI_RGB
        .biSizeImage 
= BytesPerScanLine * .biHeight
    
End With
    hDib 
= CreateDIBSection( _
            lHDC, _
            m_tBI, _
            DIB_RGB_COLORS, _
            m_lPtr, _
            
00)
    CreateDIB 
= (hDib <> 0)
End Function

Public Function CreateFromPicture( _
        
ByRef picThis As StdPicture _
    )
Dim lHDC As Long
Dim lhDCDesktop As Long
Dim lhBmpOld As Long
Dim tBMP As BITMAP
    
    GetObjectAPI picThis.handle, 
Len(tBMP), tBMP
    
If (Create(tBMP.bmWidth, tBMP.bmHeight)) Then
        lhDCDesktop 
= GetDC(GetDesktopWindow())
        
If (lhDCDesktop <> 0Then
            lHDC 
= CreateCompatibleDC(lhDCDesktop)
            DeleteDC lhDCDesktop
            
If (lHDC <> 0Then
                lhBmpOld 
= SelectObject(lHDC, picThis.handle)
                LoadPictureBlt lHDC
                SelectObject lHDC, lhBmpOld
                DeleteObject lHDC
            
End If
        
End If
    
End If
End Function

Public Function Create( _
        
ByVal lWidth As Long, _
        
ByVal lHeight As Long _
    ) 
As Boolean
    ClearUp
    m_hDC 
= CreateCompatibleDC(0)
    
If (m_hDC <> 0Then
        
If (CreateDIB(m_hDC, lWidth, lHeight, m_hDIb)) Then
            m_hBmpOld 
= SelectObject(m_hDC, m_hDIb)
            Create 
= True
        
Else
            DeleteObject m_hDC
            m_hDC 
= 0
        
End If
    
End If
End Function

Public Property Get BytesPerScanLine() As Long
    
' Scans must align on dword boundaries:
    BytesPerScanLine = (m_tBI.bmiHeader.biWidth * 3 + 3And &HFFFFFFFC
End Property


Public Property Get Width() As Long
    Width 
= m_tBI.bmiHeader.biWidth
End Property

Public Property Get Height() As Long
    Height 
= m_tBI.bmiHeader.biHeight
End Property


Public Sub LoadPictureBlt( _
        
ByVal lHDC As Long, _
        
Optional ByVal lSrcLeft As Long = 0, _
        
Optional ByVal lSrcTop As Long = 0, _
        
Optional ByVal lSrcWidth As Long = -1, _
        
Optional ByVal lSrcHeight As Long = -1, _
        
Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
    )
    
If lSrcWidth < 0 Then lSrcWidth = m_tBI.bmiHeader.biWidth
    
If lSrcHeight < 0 Then lSrcHeight = m_tBI.bmiHeader.biHeight
    BitBlt m_hDC, 
00, lSrcWidth, lSrcHeight, lHDC, lSrcLeft, lSrcTop, eRop
End Sub



Public Sub PaintPicture( _
        
ByVal lHDC As Long, _
        
Optional ByVal lDestLeft As Long = 0, _
        
Optional ByVal lDestTop As Long = 0, _
        
Optional ByVal lDestWidth As Long = -1, _
        
Optional ByVal lDestHeight As Long = -1, _
        
Optional ByVal lSrcLeft As Long = 0, _
        
Optional ByVal lSrcTop As Long = 0, _
        
Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
    )
    
If (lDestWidth < 0Then lDestWidth = m_tBI.bmiHeader.biWidth
    
If (lDestHeight < 0Then lDestHeight = m_tBI.bmiHeader.biHeight
    BitBlt lHDC, lDestLeft, lDestTop, lDestWidth, lDestHeight, m_hDC, lSrcLeft, lSrcTop, eRop
End Sub


Public Property Get hdc() As Long
    hdc 
= m_hDC
End Property

Public Property Get hDib() As Long
    hDib 
= m_hDIb
End Property

Public Property Get DIBSectionBitsPtr() As Long
    DIBSectionBitsPtr 
= m_lPtr
End Property

Public Sub RandomiseBits( _
        
Optional ByVal bGray As Boolean = False _
    )
Dim bDib() As Byte
Dim x As Long, y As Long
Dim lC As Long
Dim tSA As SAFEARRAY2D
Dim xEnd As Long
    
    
' Get the bits in the from DIB section:
    With tSA
        .cbElements 
= 1
        .cDims 
= 2
        .Bounds(
0).lLbound = 0
        .Bounds(
0).cElements = m_tBI.bmiHeader.biHeight
        .Bounds(
1).lLbound = 0
        .Bounds(
1).cElements = BytesPerScanLine()
        .pvData 
= m_lPtr
    
End With
    CopyMemory 
ByVal VarPtrArray(bDib()), VarPtr(tSA), 4

    
' random:
    Randomize Timer
    
    xEnd 
= (Width - 1* 3
    
If (bGray) Then
        
For y = 0 To m_tBI.bmiHeader.biHeight - 1
            
For x = 0 To xEnd Step 3
                lC 
= Rnd * 255
                bDib(x, y) 
= lC
                bDib(x 
+ 1, y) = lC
                bDib(x 
+ 2, y) = lC
            
Next x
        
Next y
    
Else
        
For x = 0 To xEnd Step 3
            
For y = 0 To m_tBI.bmiHeader.biHeight - 1
                bDib(x, y) 
= 0
                bDib(x 
+ 1, y) = Rnd * 255
                bDib(x 
+ 2, y) = Rnd * 255
            
Next y
        
Next x
    
End If
    
    
' Clear the temporary array descriptor
   ' This is necessary under NT4.
   CopyMemory ByVal VarPtrArray(bDib), 0&4
    
End Sub


Public Sub ClearUp()
    
If (m_hDC <> 0Then
        
If (m_hDIb <> 0Then
            SelectObject m_hDC, m_hBmpOld
            DeleteObject m_hDIb
        
End If
        DeleteObject m_hDC
    
End If
    m_hDC 
= 0: m_hDIb = 0: m_hBmpOld = 0: m_lPtr = 0
End Sub


Public Function Resample( _
        
ByVal lNewHeight As Long, _
        
ByVal lNewWidth As Long _
    ) 
As cDIBSection
Dim cDib As cDIBSection
    
Set cDib = New cDIBSection
    
If cDib.Create(lNewWidth, lNewHeight) Then
        
If (lNewWidth <> m_tBI.bmiHeader.biWidth) Or (lNewHeight <> m_tBI.bmiHeader.biHeight) Then
            
' Change in size, do resample:
            ResampleDib cDib
        
Else
            
' No size change so just return a copy:
            cDib.LoadPictureBlt m_hDC
        
End If
        
Set Resample = cDib
    
End If
End Function


Private Function ResampleDib(ByRef cDibTo As cDIBSection) As Boolean
Dim bDibFrom() As Byte
Dim bDibTo() As Byte

Dim tSAFrom As SAFEARRAY2D
Dim tSATo As SAFEARRAY2D

    
' Get the bits in the from DIB section:
    With tSAFrom
        .cbElements 
= 1
        .cDims 
= 2
        .Bounds(
0).lLbound = 0
        .Bounds(
0).cElements = m_tBI.bmiHeader.biHeight
        .Bounds(
1).lLbound = 0
        .Bounds(
1).cElements = BytesPerScanLine()
        .pvData 
= m_lPtr
    
End With
    CopyMemory 
ByVal VarPtrArray(bDibFrom()), VarPtr(tSAFrom), 4

    
' Get the bits in the to DIB section:
    With tSATo
        .cbElements 
= 1
        .cDims 
= 2
        .Bounds(
0).lLbound = 0
        .Bounds(
0).cElements = cDibTo.Height
        .Bounds(
1).lLbound = 0
        .Bounds(
1).cElements = cDibTo.BytesPerScanLine()
        .pvData 
= cDibTo.DIBSectionBitsPtr
    
End With
    CopyMemory 
ByVal VarPtrArray(bDibTo()), VarPtr(tSATo), 4

Dim xScale As Single
Dim yScale As Single

Dim x As Long, y As Long, xEnd As Long, xOut As Long

Dim fX As Single, fY As Single
Dim ifY As Long, ifX As Long
Dim dX As Single, dy As Single
Dim r As Long, r1 As Single, r2 As Single, r3 As Single, r4 As Single
Dim g As Long, g1 As Single, g2 As Single, g3 As Single, g4 As Single
Dim b As Long, b1 As Single, b2 As Single, b3 As Single, b4 As Single
Dim ir1 As Long, ig1 As Long, ib1 As Long
Dim ir2 As Long, ig2 As Long, ib2 As Long

    xScale 
= (Width - 1/ cDibTo.Width
    yScale 
= (Height - 1/ cDibTo.Height
    
    xEnd 
= cDibTo.Width - 1
        
    
For y = 0 To cDibTo.Height - 1
        
        fY 
= y * yScale
        ifY 
= Int(fY)
        dy 
= fY - ifY
        
        
For x = 0 To xEnd
            fX 
= x * xScale
            ifX 
= Int(fX)
            dX 
= fX - ifX
            
            ifX 
= ifX * 3
            
' Interpolate using the four nearest pixels in the source
            b1 = bDibFrom(ifX, ifY): g1 = bDibFrom(ifX + 1, ifY): r1 = bDibFrom(ifX + 2, ifY)
            b2 
= bDibFrom(ifX + 3, ifY): g2 = bDibFrom(ifX + 4, ifY): r2 = bDibFrom(ifX + 5, ifY)
            b3 
= bDibFrom(ifX, ifY + 1): g3 = bDibFrom(ifX + 1, ifY + 1): r3 = bDibFrom(ifX + 2, ifY + 1)
            b4 
= bDibFrom(ifX + 3, ifY + 1): g4 = bDibFrom(ifX + 4, ifY + 1): r4 = bDibFrom(ifX + 5, ifY + 1)
            
            
' Interplate in x direction:
            ir1 = r1 * (1 - dy) + r3 * dy: ig1 = g1 * (1 - dy) + g3 * dy: ib1 = b1 * (1 - dy) + b3 * dy
            ir2 
= r2 * (1 - dy) + r4 * dy: ig2 = g2 * (1 - dy) + g4 * dy: ib2 = b2 * (1 - dy) + b4 * dy
            
' Interpolate in y:
            r = ir1 * (1 - dX) + ir2 * dX: g = ig1 * (1 - dX) + ig2 * dX: b = ib1 * (1 - dX) + ib2 * dX
            
            
' Set output:
            If (r < 0Then r = 0
            
If (r > 255Then r = 255
            
If (g < 0Then g = 0
            
If (g > 255Then g = 255
            
If (b < 0Then b = 0
            
If (b > 255Then
                b 
= 255
            
End If
            xOut 
= x * 3
            bDibTo(xOut, y) 
= b
            bDibTo(xOut 
+ 1, y) = g
            bDibTo(xOut 
+ 2, y) = r
            
        
Next x
        
    
Next y

    
' Clear the temporary array descriptor
    ' This is necessary under NT4.
    CopyMemory ByVal VarPtrArray(bDibFrom), 0&4
    CopyMemory 
ByVal VarPtrArray(bDibTo), 0&4


End Function


Private Sub Class_Terminate()
    ClearUp
End Sub

 
///////////////////////图像处理函数////////////////////////////////////// void ChangeBrightness(CDib* pOrigDib, int nChange);//nChange是亮度的改变量 //改变图像亮度 pOrigDib 为原先的图像 void ChangeContrast(CDib* pOrigDib, int nChange);//nChange是对比度的改变量 //改变图像对比度 pOrigDib 为原先的图像 void Render(CDib* pOrigDib, BYTE byRed, BYTE byGreen, BYTE byBlue); //着色 void Scale(CDib* pOrigDib, int nWidth, int nHeight); //缩放图像,pOrigDib 为原先的图像,nWidth为缩放后的宽度, nHeight为缩放后的高度 void Rotate(CDib* pOrigDib, int nXCenter, int nYCenter, float fTheta); //旋转图像,pOrigDib为原图,(nXCenter,nYCenter)为旋转中心的坐标,fTheta为旋转角度 void MirrorX(CDib* pOrigDib, int x, int y, int nWidth, int nHeight); //垂直方向的镜像变换,(x,y)为起始点,nWidth,nHeight为镜像变换的区域 void MirrorY(CDib* pOirgDib, int x, int y, int nWidth, int nHeight); //水平方向的镜像变换,(x,y)为起始点,nWidth,nHeight为镜像变换的区域 void ConvolutionFilter(CDib* pOrigDib, int* pnKernel, int nRows, int nCols); //卷积滤波器,pnKernel为 nRows * nCols 的卷积核 void PercentileFilter(CDib* pOrigDib, int nPercentage, int nRows, int nCols); //百分比滤波器, nPercentage确定百分比, 模板为 nRows * nCols void ReverseColor(); //图像反色,原先x, 变为255 - x void DibCopy(CDib* pOrigDib); //重载 = 操作 void ClipRect(CDib* pDib, int x, int y, int nWidth, int nHeight); //剪切操作 //////////////////////////////////////////////////////////////////////////////// /////////////////文件存取函数/////////////////////////////////////////////////// void SaveToBMPFile(const char* pstFileName); //存为位图文件,按其自身的位数存储 void SaveToJPGFile(const char* pszJpgFileName,int nQuality); //存为JPG文件 void LoadFromJPGFile(const char* psrFileName); //从JPG文件中读取 void LoadFromBMPFile(const char* pszDibFileName); //从BMP文件中读取 void SaveAs256Bitmap(const char *pszDibFileName); //存为256色位图 void SaveAsBWBitmap(const char *pszDibFileName); //存为单色位图 void SaveAs256GrayBitmap(const char *pszDibFileName); //存为256级灰度位图 void SaveAs24BitBMPFile(const char* pstFileName); //存为24位位图 //////////////////////////////////////////////////////////////////////////////// ////////////////图像格式转换函数//////////////////////////////////////////////// bool GetHistValue(int nModulus, int nCoef, int* pRed, int* pGreen, int* pBlue, int* pGray); //取得直方图的统计数值 bool ChangeTo256Gray(CDib* pOrigDib = NULL); //将图像转换成256色灰度图,pOrigDib为待转换的图像,缺省则转换自身 void SetTo256Gray(); bool ChangeToBW(CDib* pOrigDib = NULL, int byCritical = 128); //二值化,BW: black & white, byCritical为阈值,缺省为128 void SetToBW(); void QuantizeColor(LPBYTE lpbyDibBits24, int nScanWidth, int nScanHeight, LPBYTE lpbyDibBits8, CPalette* pPalette); //对颜色进行量化, 结果被保存在逻辑调色盘pPalette中, 同时将24位数据量化为8位数据, 并存放于lpbyDdbBits8之中 //该算法保留系统默认的20种静态颜色 void SetTo24Bitmap(); //格式转换,置颜色深度为24位真彩色 void SetTo256Color(); //格式转换, 置颜色深度为256色(8位) ////////////////////////////////////////////////////////////////////////////////// #ifdef _DEBUG virtual void Dump(CDumpContext& dc) const; virtual void AssertValid() const; #endif private: void Sort(int *p, int length); //methods void Init(); int IncreaseContrast(int nOrigColor,int nChange); //OrigColor为原值,函数返回改变后的值 int DecreaseContrast(int nOrigColor,int nChange); BYTE* GetDib24Bit(DWORD nOrigSize, int nWidth, int nHeight); //将图像格式转换为24位 HPALETTE CreateBitmapPalette(); //attributes BYTE m_byUpper; //像素颜色的上阀值 BYTE m_byLower; //像素颜色的下阀值 }; #endif/*/////////////////////////////////////////////////////////////////////// // End of file 'Dib.h' // /////////////////////////////////////////////////////////////////////////////*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值