You need to download a picture (JPG, PNG etc...) into memory and show it in your GUI without writing a file?
After few hours of research and answers on question like: How can it be done? Why this way? Why me?
Here is a simple example.
I don't know why global or "byref" need to be used for input Imagebin into a function. This is only when downloaded with DownloadBin(). If downloaded with UrlDownloadToFile it can be as a function parameter.
Improvements are always welcome
Have Fun!
Code: Select all
; Tested with AHK Unicode 1.1.27.00 on Win7
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
url := "http://www.userlogos.org/files/logos/jumpordie/autohotkey_02.png" ; IMAGE URL
size := DownloadBin(url, ImageBin) ; DOWNLOAD JPG INTO VAR
BinImgToBITMAP(size, HBITMAP, 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, Text, 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 hBitmap, 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)
}
; ----------------------------------------------------------------------------------------------------------------------
; 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
c := 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, c + s, 0)
if (c > 0)
DllCall("RtlMoveMemory", "ptr", &b, "ptr", &buf, "ptr", c)
DllCall("wininet\InternetReadFile", "ptr", f, "ptr", &b + c, "uint", s, "uint*", r)
c += r
VarSetCapacity(buf, c, 0)
if (c > 0)
DllCall("RtlMoveMemory", "ptr", &buf, "ptr", &b, "ptr", c)
}
DllCall("wininet\InternetCloseHandle", "ptr", f)
}
DllCall("wininet\InternetCloseHandle", "ptr", h)
return c
}