Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include ImageEqual.ahk
- ImagePut.gdiplusStartup()
- hBitmap := ImagePutHBitmap("xd.png")
- ImagePutFile(from_hBitmap0(hBitmap), "0.png")
- ImagePutFile(from_hBitmap1(hBitmap), "1.png")
- ImagePutFile(from_hBitmap2(hBitmap), "2.png")
- if !ImageEqual("0.png", "1.png")
- MsgBox % "0, 1"
- if !ImageEqual("0.png", "2.png")
- MsgBox % "0, 2"
- if !ImageEqual("1.png", "2.png")
- MsgBox % "1, 2"
- errors := 0
- Loop 10000 {
- QPC(1)
- pBitmap0 := from_hBitmap0(hBitmap)
- control += QPC()
- QPC(1)
- pBitmap1 := from_hBitmap1(hBitmap)
- old += QPC()
- QPC(1)
- pBitmap2 := from_hBitmap2(hBitmap)
- new += QPC()
- if !ImageEqual(pBitmap0, pBitmap1) ;, pBitmap2)
- errors+=1
- ImagePut.DisposeImage(pBitmap0)
- ImagePut.DisposeImage(pBitmap1)
- ImagePut.DisposeImage(pBitmap2)
- }
- if (old > new)
- winner := "New Version wins by " old - new " and is " Abs(old - new)/new*100 "% faster."
- else
- winner := "Old Version wins by " new - old " and is " Abs(old - new)/old*100 "% faster."
- MsgBox % "Control:`t`t" control "`nOld Version:`t" old "`nNew Version:`t" new "`n" winner
- MsgBox % "Number of errors:`t" errors
- return
- Esc:: ExitApp
- from_hBitmap0(ByRef image) {
- ; This built-in version is 120% faster but ignores transparency.
- DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", image, "ptr", 0, "ptr*", pBitmap)
- return pBitmap
- }
- from_hBitmap1(ByRef image) {
- ; struct BITMAP - https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmap
- DllCall("GetObject"
- , "ptr", image
- , "int", VarSetCapacity(dib, 76+2*(A_PtrSize=8?4:0)+2*A_PtrSize)
- , "ptr", &dib) ; sizeof(DIBSECTION) = 84, 104
- , width := NumGet(dib, 4, "uint")
- , height := NumGet(dib, 8, "uint")
- ; Create a handle to a device context and associate the image.
- hdc := DllCall("CreateCompatibleDC", "ptr", 0, "ptr") ; Creates a memory DC compatible with the current screen.
- obm := DllCall("SelectObject", "ptr", hdc, "ptr", image, "ptr") ; Put the (hBitmap) image onto the device context.
- ; Create a device independent bitmap with negative height. All DIBs use the screen pixel format (pARGB).
- ; Use hbm to buffer the image such that top-down and bottom-up images are mapped to this top-down buffer.
- cdc := DllCall("CreateCompatibleDC", "ptr", hdc, "ptr")
- VarSetCapacity(bi, 40, 0) ; sizeof(bi) = 40
- , NumPut( 40, bi, 0, "uint") ; Size
- , NumPut( width, bi, 4, "uint") ; Width
- , NumPut( -height, bi, 8, "int") ; Height - Negative so (0, 0) is top-left.
- , NumPut( 1, bi, 12, "ushort") ; Planes
- , NumPut( 32, bi, 14, "ushort") ; BitCount / BitsPerPixel
- hbm := DllCall("CreateDIBSection", "ptr", cdc, "ptr", &bi, "uint", 0
- , "ptr*", pBits ; pBits is the pointer to (top-down) pixel values.
- , "ptr", 0, "uint", 0, "ptr")
- ob2 := DllCall("SelectObject", "ptr", cdc, "ptr", hbm, "ptr")
- ; This is the 32-bit ARGB pBitmap (different from an hBitmap) that will receive the final converted pixels.
- DllCall("gdiplus\GdipCreateBitmapFromScan0"
- , "int", width, "int", height, "int", 0, "int", 0x26200A, "ptr", 0, "ptr*", pBitmap)
- ; Create a Scan0 buffer pointing to pBits. The buffer has pixel format pARGB.
- VarSetCapacity(Rect, 16, 0) ; sizeof(Rect) = 16
- , NumPut( width, Rect, 8, "uint") ; Width
- , NumPut( height, Rect, 12, "uint") ; Height
- VarSetCapacity(BitmapData, 16+2*A_PtrSize, 0) ; sizeof(BitmapData) = 24, 32
- , NumPut( width, BitmapData, 0, "uint") ; Width
- , NumPut( height, BitmapData, 4, "uint") ; Height
- , NumPut( 4 * width, BitmapData, 8, "int") ; Stride
- , NumPut( 0xE200B, BitmapData, 12, "int") ; PixelFormat
- , NumPut( pBits, BitmapData, 16, "ptr") ; Scan0
- ; Use LockBits to create a writable buffer that converts pARGB to ARGB.
- DllCall("gdiplus\GdipBitmapLockBits"
- , "ptr", pBitmap
- , "ptr", &Rect
- , "uint", 6 ; ImageLockMode.UserInputBuffer | ImageLockMode.WriteOnly
- , "int", 0xE200B ; Format32bppPArgb
- , "ptr", &BitmapData) ; Contains the pointer (pBits) to the hbm.
- ; Copies the image (hBitmap) to a top-down bitmap. Removes bottom-up-ness if present.
- DllCall("gdi32\BitBlt"
- , "ptr", cdc, "int", 0, "int", 0, "int", width, "int", height
- , "ptr", hdc, "int", 0, "int", 0, "uint", 0x00CC0020) ; SRCCOPY
- ; Convert the pARGB pixels copied into the device independent bitmap (hbm) to ARGB.
- DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap, "ptr", &BitmapData)
- ; Cleanup the buffer and device contexts.
- DllCall("SelectObject", "ptr", cdc, "ptr", ob2)
- DllCall("DeleteObject", "ptr", hbm)
- DllCall("DeleteDC", "ptr", cdc)
- DllCall("SelectObject", "ptr", hdc, "ptr", obm)
- DllCall("DeleteDC", "ptr", hdc)
- return pBitmap
- }
- from_hBitmap2(ByRef image) {
- ; struct BITMAP - https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmap
- DllCall("GetObject"
- , "ptr", image
- , "int", VarSetCapacity(dib, 76+2*(A_PtrSize=8?4:0)+2*A_PtrSize)
- , "ptr", &dib) ; sizeof(DIBSECTION) = 84, 104
- , width := NumGet(dib, 4, "uint")
- , height := NumGet(dib, 8, "uint")
- ; This is the 32-bit ARGB pBitmap (different from an hBitmap) that will receive the final converted pixels.
- DllCall("gdiplus\GdipCreateBitmapFromScan0"
- , "int", width, "int", height, "int", 0, "int", 0x26200A, "ptr", 0, "ptr*", pBitmap)
- DllCall("gdiplus\GdipGetImageGraphicsContext", "ptr", pBitmap, "ptr*", pGraphics)
- /*
- ; Save original Graphics settings.
- DllCall("gdiplus\GdipGetPixelOffsetMode", "ptr",pGraphics, "int*",PixelOffsetMode) ; Default = 0; None = 3, 0?
- DllCall("gdiplus\GdipGetCompositingMode", "ptr",pGraphics, "int*",CompositingMode) ; default 0, SourceCopy = 1
- DllCall("gdiplus\GdipGetCompositingQuality", "ptr",pGraphics, "int*",CompositingQuality)
- DllCall("gdiplus\GdipGetSmoothingMode", "ptr",pGraphics, "int*",SmoothingMode)
- DllCall("gdiplus\GdipGetInterpolationMode", "ptr",pGraphics, "int*",InterpolationMode)
- MsgBox % PixelOffsetMode ", " CompositingMode ", " CompositingQuality ", " SmoothingMode ", " InterpolationMode
- */
- ;DllCall("gdiplus\GdipSetPixelOffsetMode", "ptr",pGraphics, "int",3) ; Half pixel offset.
- ;DllCall("gdiplus\GdipSetCompositingMode", "ptr",pGraphics, "int",1) ; Overwrite/SourceCopy.
- DllCall("gdiplus\GdipGetDC", "ptr", pGraphics, "ptr*", ddc)
- ; Create a handle to a device context and associate the image.
- hdc := DllCall("CreateCompatibleDC", "ptr", ddc, "ptr") ; Creates a memory DC compatible with the current screen.
- obm := DllCall("SelectObject", "ptr", hdc, "ptr", image, "ptr") ; Put the (hBitmap) image onto the device context.
- ; Copies the image (hBitmap) to a top-down bitmap. Removes bottom-up-ness if present.
- DllCall("gdi32\BitBlt"
- , "ptr", ddc, "int", 0, "int", 0, "int", width, "int", height
- , "ptr", hdc, "int", 0, "int", 0, "uint", 0x00CC0020) ; SRCCOPY
- ; Cleanup the buffer and device contexts.
- DllCall("SelectObject", "ptr", hdc, "ptr", obm)
- DllCall("DeleteDC", "ptr", hdc)
- ; Release the graphics context and delete.
- DllCall("gdiplus\GdipReleaseDC", "ptr", pGraphics, "ptr", ddc)
- DllCall("gdiplus\GdipDeleteGraphics", "ptr", pGraphics)
- return pBitmap
- }
- QPC( R := 0 ) { ; By SKAN, http://goo.gl/nf7O4G, CD:01/Sep/2014 | MD:01/Sep/2014
- Static P := 0, F := 0, Q := DllCall( "QueryPerformanceFrequency", "Int64P",F )
- Return ! DllCall( "QueryPerformanceCounter","Int64P",Q ) + ( R ? (P:=Q)/F : (Q-P)/F )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement