📄 c32bppdib.cls
字号:
' streamStart :: array position of 1st byte of the image file. Validated.
' streamLength :: total length of the image file. Validated.
' -- See LoadPicture_Stream for the validation
' Tips:
' 1) Store 32bpp bitmaps in the "Custom" resource always. Storing in the
' Bitmap resource can change color depth of the image created by VB
' depending on your screen settings
' 2) Icons, normal bitmaps, & cursors are generally stored in their own sections
' However, with icons containing multiple formats, VB will extract the
' closest format to 32x32. May want to consider storing these in "Custom"
' 3) All other types of images are normally stored in the "Custom" section
On Error GoTo ExitRoutine
Dim oWorkSpace As VB.Global, tPic As StdPicture
If VbGlobal Is Nothing Then
Set oWorkSpace = VB.Global
ElseIf TypeOf VbGlobal Is VB.Global Then
Set oWorkSpace = VbGlobal
Else
Set oWorkSpace = VB.Global
End If
If VarType(resSection) = vbString Then
Dim inStream() As Byte
' could be anything, PNG,icon,gif,32bpp bitmap,wmf, etc
inStream = oWorkSpace.LoadResData(ResIndex, resSection)
LoadPicture_Resource = LoadPicture_Stream(inStream, iconCx, iconCy, streamStart, streamLength)
Else
' can only be single icon, bitmap or cursor
Set tPic = oWorkSpace.LoadResPicture(ResIndex, resSection)
LoadPicture_StdPicture tPic
End If
LoadPicture_Resource = Not (m_Handle = 0)
ExitRoutine:
If Err Then Err.Clear
End Function
Public Function LoadPicture_StdPicture(Picture As StdPicture) As Boolean
' PURPOSE: Convert passed stdPicture into a 32bpp image
Me.DestroyDIB
If Not Picture Is Nothing Then
' simply pass off to other parsers
If Picture.Type = vbPicTypeIcon Then
' pass to icon/cursor parser
Dim cICO As New cICOParser
Call cICO.ConvertstdPicTo32bpp(Picture, Me)
Set cICO = Nothing
ElseIf Not Picture.Type = vbPicTypeNone Then
' pass to bmp,jpg,wmf parser
' Note: transparent GIFs should not be passed as stdPictures
' Pass transparent GIFs by Stream or FileName
Dim cBMP As New cBMPParser
Call cBMP.ConvertstdPicTo32bpp(Picture, Me, 0)
Set cBMP = Nothing
End If
LoadPicture_StdPicture = Not (m_Handle = 0)
End If
End Function
Public Function LoadPicture_ByHandle(Handle As Long) As Boolean
' PURPOSE: Convert passed image handle into a 32bpp image
Dim icoInfo As ICONINFO, tPic As StdPicture
If Not Handle = 0 Then
Select Case GetObjectType(Handle)
Case OBJ_BITMAP, OBJ_METAFILE, OBJ_ENHMETAFILE
' we should be able to convert this to a stdPicture...
Set tPic = iparseHandleToStdPicture(Handle, vbPicTypeBitmap)
Case Else
' Test for icons & cursors
If Not GetIconInfo(Handle, icoInfo) = 0 Then
' got it; clean up the bitmap(s) created by GetIconInfo API
If Not icoInfo.hbmColor = 0 Then DeleteObject icoInfo.hbmColor
If Not icoInfo.hbmMask = 0 Then DeleteObject icoInfo.hbmMask
' convert to stdPicture...
Set tPic = iparseHandleToStdPicture(Handle, vbPicTypeIcon)
End If
End Select
If Not tPic Is Nothing Then
' send to this routine to process
LoadPicture_ByHandle = LoadPicture_StdPicture(tPic)
End If
End If
End Function
Public Function LoadPicture_FromOrignalFormat(Optional ByVal iconCx As Long, _
Optional ByVal iconCy As Long) As Boolean
' PURPOSE: Reload the current image from the cached bytes (if any)
' If the original bytes were not cached when the image was loaded, then no action
' will be taken. See LoadPicture_File & LoadPicture_Stream
Dim tBytes() As Byte
tBytes() = m_ImageByteCache() ' copy bytes; original are destroyed when DIB is recreated
LoadPicture_FromOrignalFormat = Me.LoadPicture_Stream(tBytes, iconCx, iconCy, , , True)
End Function
Public Sub ScaleImage(ByVal destWidth As Long, ByVal destHeight As Long, newWidth As Long, newHeight As Long, Optional ByVal ScaleMode As eScaleOptions = scaleDownAsNeeded)
' Purpose: Returns the width and height needed to draw the image to the requested dimensions.
' The actual image is not modified.
' Function should be called before .Render or .Resize should you want to scale the image.
' Additionally, scaling can assist in positioning image too, i.e., centering.
' destWidth [in]:: the width of the target canvas (drawing area)
' destHeight [in]:: the height the target canvas
' NewWidth [out]:: returns the width to use for the supplied ScaleMode
' NewHeight [out]:: returns the height to use for the supplied ScaleMode
' ScaleMode [in]::
' scaleToSize [Default] - will always proportionally stretch the image to the target canvas size
' scaleDownAsNeeded - will only shrink the image if needed; otherwise the original image size is passed
' scaleStretch - the return value is always the canvas width and height; image distortion can occur
If m_Handle = 0& Then Exit Sub
Dim RatioX As Single, RatioY As Single
' calculate scale and offsets
Select Case ScaleMode
Case scaleDownAsNeeded, scaleToSize: ' scaled
RatioX = destWidth / m_Width
RatioY = destHeight / m_Height
If ScaleMode = scaleDownAsNeeded Then
If RatioX > 1! And RatioY > 1! Then
RatioX = 1!: RatioY = RatioX
End If
End If
If RatioX > RatioY Then RatioX = RatioY
newWidth = Int(RatioX * m_Width)
newHeight = Int(RatioX * m_Height)
' To center your image in the target canvas: Use the passed & returned parameters like so:
' canvasX = (destWidth - NewWidth) \ 2 + any Left offset you may be using
' canvasY = (destHeight - NewHeight) \ 2 + any Top offset you may be using
' returned results would then be passed to Render like so:
' class.Render canvasX, canvasY, NewWidth, NewHeight, .... additional optional parameters
Case ScaleStretch
newWidth = destWidth
newHeight = destHeight
Case Else
newWidth = m_Width
newHeight = m_Height
End Select
End Sub
Public Sub CopyImageTo(cDIBclass As c32bppDIB, Optional ByVal newWidth As Long, _
Optional ByVal newHeight As Long, Optional ByVal CopyOriginalFormat As Boolean = False)
' Function replicates the the current image to another DIB class and optionally resizes it
' NewWidth is optional. if zero, will use the source DIB width. If negative will mirror & resize if needed
' NewHeight is optional. if zero, will use the source DIB height. If negative will mirror & resize if needed
' If CopyOriginalFormat = True then, and only, if class loaded its image
' with the optional SaveFormat=True, then the original image bytes
' were cached and will be copied to the target cDIBclass also
' See LoadPicture_File & LoadPicture_Stream for more info
Dim dDC As Long, bUnselect As Boolean, aResized() As Byte
If Not m_Handle = 0& Then ' do we have an image to copy?
If newWidth = 0& Then newWidth = m_Width
If newHeight = 0& Then newHeight = m_Height
If cDIBclass Is Nothing Then
Set cDIBclass = New c32bppDIB ' was a valid ref passed?
cDIBclass.isGDIplusEnabled = Me.isGDIplusEnabled
cDIBclass.HighQualityInterpolation = Me.HighQualityInterpolation
cDIBclass.InitializeDIB Abs(newWidth), Abs(newHeight) ' Create new one
Else
If Not (Abs(newWidth) = cDIBclass.Width And Abs(newHeight) = cDIBclass.Height) Then
cDIBclass.InitializeDIB Abs(newWidth), Abs(newHeight) ' Create new one
End If
End If
cDIBclass.Alpha = m_AlphaImage ' carry over the alpha flag
cDIBclass.ImageType = m_Format ' and image type flag
If newWidth = m_Width And newHeight = m_Height Then
' can copy using CopyMemory vs AlphaBlend
CopyMemory ByVal cDIBclass.BitsPointer, ByVal m_Pointer, newWidth * 4& * newHeight
Else
bUnselect = (m_prevObj = 0&)
If (m_osCAP And 2) = 2 And (m_StretchQuality = True Or ((m_osCAP And 1) = 0)) Then ' use GDI+ to resize
Dim cGDIp As New cGDIPlus
dDC = cDIBclass.LoadDIBinDC(True)
If bUnselect Then Me.LoadDIBinDC True
cGDIp.RenderGDIplus Me, dDC, 0&, 100&, 0&, 0&, newWidth, newHeight, 0&, 0&, m_Width, m_Height, True
cDIBclass.LoadDIBinDC False
Set cGDIp = Nothing
If bUnselect Then Me.LoadDIBinDC False
ElseIf newWidth < 0& Or newHeight < 0& Then ' handle mirroring, AlphaBlend cannot do mirroring
MirrorDIB 0&, 0&, 0&, 0&, newWidth, newHeight, aResized(), cDIBclass ' routine mirrors directly to DIB bytes
ElseIf (m_osCAP And 1) = 1 And m_StretchQuality = False Then ' O/S has no alphablending shortfalls that are known
dDC = cDIBclass.LoadDIBinDC(True) ' load target into a DC
If bUnselect Then Me.LoadDIBinDC True
Me.Render dDC, 0&, 0&, newWidth, newHeight, 0&, 0&, m_Width, m_Height
cDIBclass.LoadDIBinDC False ' remove DIB from DC
If bUnselect Then Me.LoadDIBinDC False
Else
' stretching is involved, resize
Call pvResize(0&, aResized(), aResized(), cDIBclass) ' routine resizes directly to DIB bytes
End If
End If
' if the original image bytes are to be copied, do them too
If CopyOriginalFormat = True Then Call cDIBclass.SetOriginalFormat(m_ImageByteCache)
End If
End Sub
Public Function GetOrginalFormat(outStream() As Byte) As Boolean
' If SaveFormat is true when LoadPicture_Stream or LoadPicture_File was
' called, the original bytes were cached when the image was successfully
' loaded. Call this to return those original bytes
' If there are no original bytes, the function returns False
outStream() = m_ImageByteCache()
GetOrginalFormat = Not iparseIsArrayEmpty(Not m_ImageByteCache)
End Function
Friend Property Let Alpha(isAlpha As Boolean)
m_AlphaImage = isAlpha ' determines the flags used for AlphaBlend API
' this flag is set by the various image parsers; setting it yourself
' can produce less than desirable effects.
' Used in cGDIPlus.SaveToPNG, Me.Render & Me.TrimImage, cPNGwriter.OptimizeTrueColor & cPNGwriter.PalettizeImage
End Property
Public Property Get Alpha() As Boolean
Alpha = m_AlphaImage
End Property
Public Property Let HighQualityInterpolation(Value As Boolean)
' When possible GDI+ will be used for stretching, rotation.
' If GDI+ is used,then high quality equates to BiCubic interpolation
' If not used, then BiLinear (manual processing) will be used.
' If High Quality is false, then Nearest Neighbor (very fast) interpolation used
m_StretchQuality = Value
End Property
Public Property Get HighQualityInterpolation() As Boolean
HighQualityInterpolation = m_StretchQuality
End Property
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -