二进制图像下载到var_转换为位图并在Gui中显示.ahk

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=44115
; Tested with AHK Unicode 1.1.27.00 on Win7
#NoEnv
SetWorkingDir %A_ScriptDir% 

url := "http://www.userlogos.org/files/logos/jumpordie/autohotkey_02.png"		; IMAGE URL

size := DownloadBin(url, ImageBin)  ; DOWNLOAD JPG INTO VAR
hBitmap := BinImgToBITMAP(size, Imagebin)  ; CONVERT BINARY TO BITMAP

H := Bitmap_GetHeight(HBITMAP)  ; GET IMAGE HEIGHT
W := Bitmap_GetWidth(HBITMAP)  ; GET IMAGE WIDTH
Gui, Margin, 0, 0
Gui, Add, Picture, vPic, % "HBITMAP:*" hBitmap
Gui, Show, , AHK窗口显示

; Gui, Add, Picture, x0 y0 w%W% h%H% hwndHPic1 ; IMAGE POSITION
; Bitmap_SetImage(HPic1, HBITMAP)  ; SET IMAGE TO A GIVEN hwnd
; Gui, Show, , Image  ; SHOW GUI
return

; -----------------------------------------------------------------------
; Convert Binary Image to Bitmap.
; -----------------------------------------------------------------------
BinImgToBITMAP(size, byref Imagebin) {
  ; if hBitmap
  ; 	DllCall("DeleteObject", "ptr", hBitmap)
  hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", size, "UPtr")
  pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
  DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &ImageBin, "UPtr", size)
  DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
  DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
  hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
  VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
  DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
  DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
  DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
  DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
  DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
  DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
  DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
  Return hBitmap
}

; -----------------------------------------------------------------------
; Returns the width of a bitmap.
; -----------------------------------------------------------------------
Bitmap_GetWidth(hBitmap) {
  Static Size := (4 * 5) + A_PtrSize + (A_PtrSize - 4)
  VarSetCapacity(BITMAP, Size, 0)
  DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", Size, "Ptr", &BITMAP, "Int")
  Return NumGet(BITMAP, 4, "Int")
}
; -----------------------------------------------------------------------
; Returns the height of a bitmap.
; -----------------------------------------------------------------------
Bitmap_GetHeight(hBitmap) {
  Static Size := (4 * 5) + A_PtrSize + (A_PtrSize - 4)
  VarSetCapacity(BITMAP, Size, 0)
  DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", Size, "Ptr", &BITMAP, "Int")
  Return NumGet(BITMAP, 8, "Int")
}
; -----------------------------------------------------------------------
; Associates a new bitmap with a static control.
; Parameters:   hCtrl  -  Handle to the GUI control (Pic or Text).
;         hBitmap  -  Handle to the bitmap to associate with the GUI control.
; Return value:   Handle to the image previously associated with the GUI control, if any; otherwise, NULL.
; -----------------------------------------------------------------------
Bitmap_SetImage(hCtrl, hBitmap) {
  ; STM_SETIMAGE = 0x172, IMAGE_BITMAP = 0x00, SS_BITMAP = 0x0E
  WinSet, Style, +0x0E, ahk_id %hCtrl%
  SendMessage, 0x172, 0x00, %hBitmap%, , ahk_id %hCtrl%
  DllCall("DeleteObject", "ptr", ErrorLevel)		;  Delete Objects for prevent memory leak
  DllCall("DeleteObject", "Uint", hBitmap)	
  Return ErrorLevel
}

; DOWNLOAD BIN DATA TO A VARIABLE
DownloadBin(url, byref buf)
{
  static a := "AutoHotkey/" A_AhkVersion
  if (!DllCall("LoadLibrary", "str", "wininet") || !(h := DllCall("wininet\InternetOpen", "str", a, "uint", 1, "ptr", 0, "ptr", 0, "uint", 0, "ptr")))
    return 0
  size := s := 0
  if (f := DllCall("wininet\InternetOpenUrl", "ptr", h, "str", url, "ptr", 0, "uint", 0, "uint", 0x80003000, "ptr", 0, "ptr"))
  {
    while (DllCall("wininet\InternetQueryDataAvailable", "ptr", f, "uint*", s, "uint", 0, "ptr", 0) && s > 0)
    {
      VarSetCapacity(b, size + s, 0)
      if (size > 0)
        DllCall("RtlMoveMemory", "ptr", &b, "ptr", &buf, "ptr", size)
      DllCall("wininet\InternetReadFile", "ptr", f, "ptr", &b + size, "uint", s, "uint*", r)
      size += r
      VarSetCapacity(buf, size, 0)
      if (size > 0)
        DllCall("RtlMoveMemory", "ptr", &buf, "ptr", &b, "ptr", size)
    }
    DllCall("wininet\InternetCloseHandle", "ptr", f)
  }
  DllCall("wininet\InternetCloseHandle", "ptr", h)
  return size
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。