📄 c32bppdib.cls
字号:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "c32bppDIB"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit
' Credits/Acknowledgements - Thanx goes to:
' Paul Caton for his class on calling non VB-Friendly DLLs that use _cdecl calling convention
' Alfred Koppold for his PNG, VB-only, decompression routines
' www.zlib.net for their free zLIB.dll, the standard DLL for compressing/decompressing PNGs
' coders like you that provide constructive criticism to make this class better & more all-inclusive
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' QUICK OVERVIEW
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' About 32bpp pre-multiplied RGB (pARGB) bitmaps, if you are not aware.
' - These are used specifically for the AlphaBlend API & are GDI+ compatible
' Advantages:
' - Images can be per-pixel alpha blended
' - Opacity can be simultaneously adjusted during rendering
' - AlphaBlend does both BitBlt & StretchBlt for pARGB images.
' - Speed: AlphaBlend & GDI+ are pretty quick APIs vs manual blending
' Disadvantages:
' - The original RGB values are permanently destroyed during pre-multiplying
' -- there is no way to convert pARGB back to non-premultiplied RGB values
' -- the formula would be: reconstructedRed=(preMultipliedRed * 255) \ Alpha.
' but because of integer division when pre-multiplying the result is only close
' and if this should be premultiplied again & converted again, the results can get worse
' - Displaying a pre-multiplied bitmap without AlphaBlend will not result in
' the image being displayed as expected.
' - Not ideal for saving due to its size: SizeOf= W x H x 4
' -- better to save source image instead or compress the DIB bytes using favorite compression utility
' -- with GDI+, image can be converted to PNG for storage
' - AlphaBlend (msimg32.dll) is not included with Win95, NT4 and lower
' Note that GDI+ is standard on WinXP+, and can be used on Win98,ME,2K, & on NT4 if SP6 is installed
' About Win95, Win98, NT3.5, NT4 & WinME support
' ----------------------------------------------
' The routines will not honor AlphaBlend if it exists on those systems. Win98's version,
' for example, has several bugs that can crash the application when AlphaBlending to DIBs.
' NT4, NT3.5 & Win95 do not come with AlphaBlend and I do not have WinME to test with.
' Therefore, to support these systems, the Render routine will alphablend manually
' regardless if the AlhpaBlend API (msimg32.dll) exists on the system or not.
' Table of methods used for rendering dependent upon class settings and O/S
' Win2K or Better? GDI+ Available? HighQualityInterpolation? Method of Rendering
' Yes Yes No / Yes AlphaBlend / GDI+
' No Yes No / Yes GDI+ / GDI+
' Yes No No / Yes AlphaBlend / Manually
' No No No / Yes Manually / Manually
' Note that AlphaBlend does not support mirroring nor rotation nor high quality interpolation,
' so if these are applied when rendering, then class will use GDI+ if available,
' otherwise, manually rendered. By default, the class will initialize with
' HighQualityInterpolation=True if GDI+ is available.
' Class Purpose:
' This class holds the 32bpp image. It also marshals any new image thru
' the battery of parsers to determine best method for converting the image
' to a 32bpp alpha-compatible image. It handles rendering, rotating, scaling,
' mirroring of DIBs using manual processes, AlphaBlend, and/or GDI+.
' What about DirectX? Hmmmm...
' The parser order is very important for fastest/best results...
' cPNGparser :: will convert PNG, all bit depths; aborts quickly if not PNG
' cGIFparser :: will convert non-transparent/transparent GIFs; aborts quickly
' cICOpraser :: will convert XP-Alpha, paletted, true color, & Vista PNG icons
' -- can also convert most non-animated cursors
' cBMPparser :: will convert bitmaps, wmf/emf & jpgs
' The parsers are efficient. Most image formats have a magic number that give
' a hint to what type of image the file/stream is. However, checks need to
' be employed because non-image files could feasibly have those same magic
' numbers. If the image is determined not to be one the parser is designed
' to handle, the parser rejects it and the next parser takes over. The
' icon parser is slightly different because PNG files can be included into
' a Vista ico file. When this occurs, the icon parser will pass off the
' PNG format to the PNG parser automatically.
' And last but not least, the parsers have no advanced knowledge of the image
' format; as far as they are concerned, anything passed is just a byte array
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' CHANGE HISTORY
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' Accompanying FAQ.rtf is updated with every change
' 20 Feb 07:
' - PNGparser conversion routines overhauled for speed, minor error found & fixed
' -- PNGparser.InitializePalette did not correctly identify transparency index for Grayscale with simple transparency
' - PNGwriter.FormatCaption & FormatText recognized non-spec text but did not prevent it from being written to PNG
' - Modified PNGwriter to use zLIB compress2 function when available
' - Error on my part, last post had debugging code using zLibVB.dll vs zLib.dll
' -- no serious harm but versions prior to this update probably will not be able to use zlib.net's zLib.DLL
' 18 Feb 07:
' - Bugs recognized & fixed
' -- cPNGwriter.OptimizeTrueColor could error when converting to 24bpp images
' -- cPNGwriter.OptimizeTrueColor was not writing the single transparency color for 24bpp converted images
' -- cPNGwriter.Write_tRNS was not always writing the tranpsarency color either
' -- PngPropertySet was not honoring the user-selected filterMethod property
' 16 Feb 07:
' - More PNG support....(First non-GDI+ PNG writer in VB open source? Maybe.)
' -- Added cPNGwriter class. Can create PNGs using zLIB.dll versions. See class for more
' -- Added cCDECL class. Allows calling zLIB.dll when zLIB is not VB-friendly
' -- added modParsers.iparseValidateZLIB to determine if zLIB is available & if VB-friendly
' -- required adding some custom zLIB calls to end of cPngWriter & cPngParser classes
' -- added PngPropertySet to allow PNG creation options not possible w/GDI+. Must have zLIB available
' -- added PngPropertyGet to retrieve settings. Over a dozen options
' -- added isZlibEnabled property to inform you if zLIB can be used or not
' -- Modified SaveToStream_PNG & SaveToFile_PNG to use zLIB if GDI+ is not available,
' but zLIB is or vice versa. zLIB is prefered when pngPropertySet is called
' -- Zlib is 100% free and is available directly from source: www.zlib.net
' 11 Feb 07:
' - Logic error. When a DIB is first initialized, the Alpha property is False.
' This should have been Alpha=True. Note that if you are creating blank DIBs and rendering other
' DIBs to the blank one, you should change the blank DIB's alpha and image format properties as
' appropriate, dependent upon what you are rendering to that DIB. The Alpha property is used in
' other routines and must be accurate, but the ImageType property is not used
' - Added imgError to the ImageType property enumeration. This can assist when self-rendering
' DIBs. If ImageType=imgError then Handle=0& and no DIB has been loaded into the class.
' 10 Feb 07:
' - Added LoadPicture_FromOrignalFormat routine which will recreate the DIB from the bytes
' cached during a call to LoadPicture_File or LoadPicture_Stream
' - Added TrimImage routine which will remove excess transparency from an image
' If a 256x256 image has 20x20 transparency border around it, the image will be reduced to 216x216
' - When calling Resize, class would not save original image bytes if they existed; now it does
' - Minor tweaks in rotation routines. Routines no longer overwrite class' Interpolation setting
' - Logic error fixed: GDI+ when rendering mirrored & rotated used incorred DC X,Y coordinates
' 4 Feb 07:
' - Added SaveToFile_PNG & SaveToStream_PNG as main class options, but only supported if isGDIplusEnabled = True
' - Complete revamp of mirroring routines.
' -- Added MirrorDIB routine that mirrors an image as needed & mirrored bytes are later rotated, scaled, rendered
' -- Previous version attempted to calculate mirroring offsets when scaling, rotating, rendering -- failed
' -- Following routines modified: pvResize, CopyImageTo, Resize, RotateAtTopLeft
' - Logic error fixed: pvResize would clip wrong end of image when image is rendered past vertical bounds of DC.
' - Modified startup to always set HighQualityInterpolation if GDI+ is available.
' 1 Feb 07: By request...
' - Added mirroring support to following routines. Passing a negative destination width and/or height causes mirroring
' - pvResize, Win9xBlend, CopyImageTo, Resize, RotateAtCenterPoint, RotateAtTopLeft & cGDIPlus.RenderGDIplus
' - The msimg32.dll AlphaBlend API cannot perform mirroring. Therefore...
' - Whenever mirroring is in effect and GDI+ can't be used, mirroring will be done manually
' - GDI+, if available, will only perfrorm the mirroring if also rotating or if HighQualityInterpolation=True
' - Found another minor bug. Broke GDI+ ability to Global blend while rotating. Fixed.
' 31 Jan 07:
' - Fixed logic error when rotating negative angles via GDI+ (cGDIPlus.RenderGDIplus routine)
' - Fixed logic error when manually resizing using BiLinear method (pvResize routine)
' - routines were combining current pixel with one above, not below as required
' - Fixed rotation routines (non-GDI+); now rotation while non-proportional scaling compatible
' - Renamed cPNGParser.SaveTo routine to cGDIPlus.SaveToPNG. See Change 4Jan07 below for more
' 30 Jan 07:
' - Added rotation options. See RotateAtCenterPoint & RotateAtTopLeft
' - The two routines are identical except for how the destination X,Y coords are determined
' - Added isGDIplusEnabled property to inform you whether or not GDI+ can be used on the system
' - Added HighQualityInterpolation property to produce better renderings
' - When set to True & GDI+ is available, any rendering is done by GDI+
' - When set to True and GDI+ is not available, manual interpolation is done when scaling/rotating
' - Property can be set to False manually to prevent GDI+ usage
' - Added MakeGrayScale routine. Irreversible pixel modifications
' - 3 different grayscale formulas are provided
' - Relocated all GDI+ function calls and related code into a new class: cGDIPlus
' - Relocated cPNGparser.ValidateDLL to modParsers as iparseValidateDLL
' 25 Jan 07:
' - Modified Win9xBlend routine. Did not exactly replicate AlphaBlend when stretching; fixed I believe
' -- Added extra checks in Win9xBlend & pvResize when alphablending on Win9x systems.
' -- Prevents user from supplying invalid values that could cause routines to read past allocated memory
' -- Properly handles negative destination DC offsets
' - Changed iswin95Alpha property to isAlphaBlendFriendly to indicate whether or not AlphaBlend will be used
' 24 Jan 07:
' - Now compatible with all O/S. Added Win95/NT4 support to the following routines:
' CopyImageTo, Resize, Render
' -- Added Win9xBlend & heavily modified then added Carles P.V.'s pvResize routine
' - Bug found. cPNGparser.vbDecompress, under NT4, was causing crashes when trying to
' resize a passed byte array. Fixed. Array is sized before it is passed to that routine
' - Bug found. The iparseCreateShapedRegion routine was creating shaped regions bottom up
' and this crashed on NT4. Fixed so regions are created top down always
' - Bug found. In Win98 & possibly other O/S. When VB creates a 24bpp stdPicture as used
' in cBMPparser, the stdPicture.Render method can write into the alpha channel of the
' destination 32bpp DIB; 24bpp has no alpha channel. Routine tweaked to handle that.
' 17 Jan 07:
' - Added CreateCheckerBoard method. This method will create a checkerboard pattern
' as the DIB image. It will also set the ImageType property to imgCheckerBoard
' so you know whether or not the image is class checkerboard or not.
' This can be useful when the DIB should be displayed, but has no image to display.
' The flag can be used to determine saving the image. If imgCheckerboard then noSave
' - Added Resize method to permanently resize the image within the DIB
' - Added optional resizing parameters to CopyImageTo routine
' - Tweaked cBMPparser & cGIFparser to always modify alpha bytes regardless of transparency
' -- Previously, when image had no transparency, the alpha bytes were not touched, rather
' the class tracked this information via its Alpha property. But if you wanted to pass
' the DIB to some other routine in your project and process/render it, the unmodified
' alpha bytes could prove to fool those processes/routines
' - Tweaked Render method to fully expose all of AlphaBlend's parameters
' - LoadPicture_StdPicture could not process WMFs, fixed
' - LoadDIBinDC fixed - could fail if multiple calls made passing a True parameter
' - Error in LoadPictureEx prevented saving image bytes when PNG file was loaded, fixed
' 5 Jan 07:
' - Added SaveFormat parameter to LoadPicture_File & LoadPicture_Stream
' -- option has class cache the original bytes of the image if loaded
' -- the 32bpp DIB will always be larger than the source bytes and for
' usercontrols, saving the original bytes takes less space than
' saving the DIB bytes.
' - Added GetOrginalFormat to retrieve bytes when SaveFormat was passed as True
' - Added SetOriginalFormat used when copying one DIB class to another
' 4 Jan 07:
' - Added LoadPicture_ByHandle, LoadPicture_StdPicture, ScaleImage & CopyImageTo
' - Added cGDIPlus.SaveToPNG (testing). Requires GDI+ or zLIB but will save 32bpp to PNG file or stream
' -- not accessible, right now, from c32bppDIB. Must create cGDIPlus class to use it.
' - Modified cICOparser's GetBestMatch algorithm
' - Added imgPNGicon as an image type to distinguish PNG in Vista Icon vs standard .PNG file
' - Bug found: removing overlays in cGIFparser.ConvertGIFto32bpp; forgot ByVal VarPtrArray(...)
' which could cause crash when compiled. Fixed & double checked everywhere else too
' 1 Jan 07:
' - Added SaveToFile & SaveToStream methods
' - cBMPparser could possibly try to query unauthorized memory; fixed
' - Methodology changed a bit when parsers return results. If image is definitely one
' that the parser is responsible for & the image is invalid, the parser will return
' True to prevent other parsers from handling the image. The c32bppDIB.Handle is used
' to determine true success or failure.
' -- cGIFparser when recognizing improperly formatted GIF would allow image to continue to
' other parsers which then may cause those parsers to lock up.
' 26 Dec 06: First version
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
' No APIs are declared public. This is to prevent possibly, differently
' declared APIs, or different versions of the same API, from conflciting
' with any APIs you declared in your project. Same rule for UDTs.
' Note: I did take liberties, changing parameter types, in several APIs throughout
' Used to determine operating system
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As Any) As Long
Private Const VER_PLATFORM_WIN32_WINDOWS As Long = &H1
Private Type OSVERSIONINFOEX
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128 ' up to here is OSVERSIONINFO vs EX
wServicePackMajor As Integer ' 8 bytes larger than OSVERSIONINFO
wServicePackMinor As Integer
wSuiteMask As Integer
wProductType As Byte
wReserved As Byte
End Type
' APIs used to manage the 32bpp DIB
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hDC As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long, ByRef pBitmapInfo As Any, ByVal un As Long, ByRef Pointer As Long, ByVal Handle As Long, ByVal dw As Long) As Long
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal nHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal lBlendFunction As Long) As Long
Private Declare Function SetStretchBltMode Lib "gdi32.dll" (ByVal hDC As Long, ByVal nStretchMode As Long) As Long
Private Declare Function GetObjectType Lib "gdi32.dll" (ByVal hgdiobj As Long) As Long
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -