' 發展單位:風禹科技驗證有限公司 ' 撰寫人:鄭子璉(Tzu-Lien, Cheng, 璉璉) ,成大水利博肄,微軟最有價值專家 ' Web: http://tlcheng.twbbs.org/TLCheng/ E-Mail: qvb3377@ms5.hinet.net ' -------------------------------------------------------------------------------------- Module modGraphic #Region "DCMemoryBitmap" Private Class DCMemoryBitmap Private m_hDC As IntPtr Private m_BitmapInfoHeader As BITMAPINFOHEADER Private m_hBitmap As IntPtr Private dibBitmap As IntPtr Private ppvBits As IntPtr Private oldObject As IntPtr Private m_HasImage As Boolean = False Public ReadOnly Property hDC() As IntPtr Get Return m_hDC End Get End Property Public ReadOnly Property hBitmap() As IntPtr Get Return m_hBitmap End Get End Property Public Function ToImage() As Bitmap If m_HasImage Then Return Bitmap.FromHbitmap(dibBitmap) Else Return Nothing End Function Private Sub CreateNew(ByVal Width As Integer, ByVal Height As Integer) m_hDC = CreateCompatibleDC(IntPtr.Zero) With m_BitmapInfoHeader .biBitCount = 32 .biHeight = Height .biSize = System.Runtime.InteropServices.Marshal.SizeOf(m_BitmapInfoHeader) .biWidth = Width .biPlanes = 1 End With dibBitmap = CreateDIBSection(m_hDC, m_BitmapInfoHeader, 0, ppvBits, 0, 0) oldObject = SelectObject(m_hDC, dibBitmap) m_HasImage = True End Sub ''' <summary>依指定尺寸建立空白DC</summary> ''' <param name="Width">寬度,Pixel</param> ''' <param name="Height">高度,Pixel</param> Public Sub New(ByVal Width As Integer, ByVal Height As Integer) CreateNew(Width, Height) End Sub ''' <summary>依原圖檔建立DC</summary> ''' <param name="vImage">來源圖檔</param> ''' <param name="bCopy">是否將圖面繪製到 DC 上,預設繪製</param> Public Sub New(ByVal vImage As Bitmap, Optional ByVal bCopy As Boolean = True) If bCopy Then CreateNew(vImage.Width, vImage.Height) Dim srcBmp As New DCMemoryBitmap(vImage, False) BitBlt(hDC, 0, 0, vImage.Width, vImage.Height, srcBmp.hDC, 0, 0, RasterOperationCode.SrcCopy) GdiFlush() Else m_hDC = CreateCompatibleDC(IntPtr.Zero) m_hBitmap = vImage.GetHbitmap oldObject = SelectObject(m_hDC, m_hBitmap) End If m_HasImage = True End Sub Protected Overrides Sub Finalize() MyBase.Finalize() If m_HasImage Then SelectObject(m_hDC, oldObject) DeleteObject(dibBitmap) DeleteObject(ppvBits) DeleteObject(oldObject) DeleteDC(m_hDC) End If m_HasImage = False End Sub End Class #End Region #Region "Windows API 宣告" <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function CreateCompatibleDC( _ ByVal hDC As IntPtr _ ) As IntPtr End Function <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function DeleteDC( _ ByVal hObject As Integer _ ) As Integer End Function <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function GdiFlush() As Integer End Function <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function CreateDIBSection( _ ByVal hDC As IntPtr, _ ByRef pBitmapInfo As BITMAPINFOHEADER, _ ByVal iUsage As Integer, _ ByVal ppvBits As IntPtr, _ ByVal hSection As Integer, _ ByVal dwOffset As Integer _ ) As IntPtr End Function ' 點 <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function GetPixel( _ ByVal hDC As IntPtr, _ ByVal X As Integer, _ ByVal Y As Integer _ ) As Integer End Function ' 色筆 <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function CreateSolidBrush( _ ByVal crColor As Integer _ ) As IntPtr End Function ' 在裝置環境上選擇使用物件 <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function SelectObject( _ ByVal hDC As IntPtr, _ ByVal hObject As IntPtr _ ) As Integer End Function <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function DeleteObject( _ ByVal hObject As IntPtr _ ) As Integer End Function ' 填滿 <Runtime.InteropServices.DllImport("gdi32.dll", EntryPoint:="ExtFloodFill")> _ Private Function apiFloodFill( _ ByVal hDC As IntPtr, _ ByVal X As Integer, _ ByVal Y As Integer, _ ByVal crColor As Integer, _ ByVal fuFillType As FloodFillType _ ) As Integer End Function <Runtime.InteropServices.DllImport("User32.dll")> _ Private Function FillRect( _ ByVal hDC As IntPtr, _ ByRef lpRect As apiRect, _ ByVal hBrush As IntPtr _ ) As Integer End Function <Runtime.InteropServices.DllImport("gdi32.dll")> _ Private Function BitBlt( _ ByVal hDCofTarget As IntPtr, _ ByVal x As Integer, _ ByVal y As Integer, _ ByVal nWidth As Integer, _ ByVal nHeight As Integer, _ ByVal hDCofSource As IntPtr, _ ByVal xSrc As Integer, _ ByVal ySrc As Integer, _ ByVal opCode As RasterOperationCode) As Integer End Function Private Structure BITMAPINFOHEADER Dim biSize As Integer Dim biWidth As Integer Dim biHeight As Integer Dim biPlanes As Short Dim biBitCount As Short Dim biCompression As Integer Dim biSizeImage As Integer Dim biXPelsPerMeter As Integer Dim biYPelsPerMeter As Integer Dim biClrUsed As Integer Dim biClrImportant As Integer End Structure <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> Private Structure apiPoint Public x As Integer Public y As Integer End Structure <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> Private Structure apiRect <Runtime.InteropServices.FieldOffset(0)> Public Left As Integer <Runtime.InteropServices.FieldOffset(4)> Public Top As Integer <Runtime.InteropServices.FieldOffset(8)> Public Right As Integer <Runtime.InteropServices.FieldOffset(12)> Public Bottom As Integer Public Sub New(ByVal vRect As Rectangle) With vRect Left = .Left Top = .Top Right = .Right Bottom = .Bottom End With End Sub End Structure ' 填滿 Public Enum FloodFillType As Integer Border = 0 Surface = 1 End Enum Public Enum RasterOperationCode As Integer BLACKNESS = &H42 DSINVERT = &H550009 MERGECOPY = &HC000CA MERGEPAINT = &HBB0226 NOTSRCCOPY = &H330008 NOTSRCERASE = &H1100A6 PATCOPY = &HF00021 PATINVERT = &H5A0049 PATPAINT = &HFB0A09 SrcAnd = &H8800C6 SrcCopy = &HCC0020 SrcErase = &H4400328 SrcInvert = &H660046 SrcPaint = &HEE0086 WHITENESS = &HFF0062 End Enum Public Function PaintImage(ByVal targetImage As Bitmap, ByVal sourceImage As Bitmap, ByVal vLocation As Drawing.Point, ByVal vRectangle As Rectangle, Optional ByVal opCode As RasterOperationCode = RasterOperationCode.SrcCopy) As Bitmap Dim dcSource As New DCMemoryBitmap(sourceImage, False) Dim dcTarget As New DCMemoryBitmap(targetImage) BitBlt(dcTarget.hDC, vRectangle.X, vRectangle.Y, vRectangle.Width, vRectangle.Height, dcSource.hDC, vLocation.X, vLocation.Y, opCode) GdiFlush() Return dcTarget.ToImage End Function Public Function FloodFill(ByVal vImage As Bitmap, ByVal X As Integer, ByVal Y As Integer, ByVal FillColor As Color, Optional ByVal fuFillType As FloodFillType = FloodFillType.Surface) As Bitmap If vImage Is Nothing Then Return Nothing Dim dcBitmap As New DCMemoryBitmap(vImage) Dim rtnFloodFill As Integer Dim apiColor As Integer = ColorTranslator.ToWin32(FillColor) 'Dim apiColor As Integer = ColorTranslator.ToOle(FillColor) Dim hDC As IntPtr = dcBitmap.hDC Select Case fuFillType Case FloodFillType.Border rtnFloodFill = apiFloodFill(hDC, X, Y, apiColor, fuFillType) Case FloodFillType.Surface Dim hSolidBrush As IntPtr = CreateSolidBrush(apiColor) Dim hOldSolidBrush As IntPtr = SelectObject(hDC, hSolidBrush) Dim crColor As Integer = GetPixel(hDC, X, Y) rtnFloodFill = apiFloodFill(hDC, X, Y, crColor, fuFillType) hOldSolidBrush = SelectObject(hDC, hOldSolidBrush) DeleteObject(hSolidBrush) End Select Return dcBitmap.ToImage End Function #End Region End Module