Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Load and Display Images(png, jpg) with LoadScriptResource()


  • Please log in to reply
1 reply to this topic
  • Guests
  • Last active:
  • Joined: --
Hi,

With the function introduced in this FileExtract / FileExtract_ToMem Examples for Unicode Builds, I succeeded to show images of icon and bitmap from resources in compiled scripts. I'd like to know a way to do it with jpg and png files.

Is it possible? It's preferable to avoid using GDI+ since some OSes don't have it by default.

This example script demonstrates showing an icon image from the resource. It requires sample.ico with the size 64x64 in the script folder.
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

if A_IsCompiled {
	If size := LoadScriptResource(buf,".\sample.ico")
		hIcon := HIconFromBuffer(buf, 64, 64)
	else MsgBox Resource could not be loaded!
} else {
	FileRead, buf, *c %A_ScriptDir%\sample.ico
	hIcon := HIconFromBuffer(buf, 64, 64)
}

Gui, Margin, 20, 20
Gui, Add, Picture, w64 h64 0x3 hWndPic1      	;0x3 = SS_ICon
SendMessage, STM_SETICON := 0x0170, hIcon, 0,, ahk_id %Pic1%
Gui, Show 

Return
GuiClose:
   Gui, Destroy
   hIcon := hIcon := "" 
   ExitApp   
Return

LoadScriptResource(ByRef Data,Name, Type = 10)
{
	; originally posted by Lexikos, modified by HotKeyIt 
	; http://www.autohotkey.com/forum/post-516086.html#516086

    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")
    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")
    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")
    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")
    VarSetCapacity(Data,DataSize)
    DllCall("RtlMoveMemory","PTR",&Data,"PTR",DllCall("LockResource", "ptr", hresdata, "ptr"),"UInt",DataSize)
    return DataSize
}
HIconFromBuffer(ByRef Buffer, width, height) {
	;Ptr := Ptr ? "Ptr" : "Uint"	; For AutoHotkey Basic Users
	hIcon := DllCall( "CreateIconFromResourceEx"
		, UInt, &Buffer+22
		, UInt, NumGet(Buffer,14)
		, Int,1
		, UInt, 0x30000
		, Int, width
		, Int, height
		, UInt, 0
		, Ptr) 	
	return hIcon
}

FileInstall, .\sample.ico, ~
An example for bmp file is posted by HotKeyIt here. Thanks.

  • Guests
  • Last active:
  • Joined: --
Okey, I found a way to show png file with GDIplus functions.

There are problems though. Could somebody solve these?
1. nSize := StrLen(Buffer) * 2 I don't understand why the size has to be multiplied by two.
2. It doesn't work with resource buffer (compiled script).
3. It uses GDIplus functions so I'd like to know a way without them.
4. I'd like to do the same thing with jpeg and gif images.

It requires sample.png in the script directory.
width := 512
height := 384
sFile := A_ScriptDir "\sample.png"

if A_IsCompiled {
   If size := LoadScriptResource(buf,".\sample.png")
      hBitmap := hBMPFromPNGBuffer(buf, width, height)
   else MsgBox Resource could not be loaded!
} else {
	if FileExist(sFile)
		FileRead, buf, *c %sFile%
	else msgbox File Not Found
	hBitmap := hBMPFromPNGBuffer(buf, width, height)	
} 
if !hBitmap {
	msgbox Could not load the image
	ExitApp
}

Gui, Margin, 20, 20
Gui, Add, Text, w%width% h%height% +0xE hWndPic1 ; +0xE is SS_BITMAP
SendMessage, (STM_SETIMAGE:=0x172), (IMAGE_BITMAP:=0x0), % hBitmap,, ahk_id %Pic1%
Gui, Show,, 
Return                                                    ; // End of Auto-Execute section

GuiClose:
GuiEscape:
ExitApp
  
hBMPFromPNGBuffer(ByRef Buffer, width, height) {
	;modified SKAN's code ; http://www.autohotkey.com/forum/post-147052.html#147052
	
	; for AutoHotkey Basic users
	; Ptr := A_PtrSize ? "Ptr" : "Uint" , PtrP := A_PtrSize ? "PtrP" : "UIntP"
	
	nSize := StrLen(Buffer) * 2 ;// 2 ; <-- I don't understand why it has to be multiplied by 2
	hData := DllCall("GlobalAlloc", UInt, 2, UInt, nSize, Ptr)
	pData := DllCall("GlobalLock", Ptr, hData , Ptr)
	DllCall( "RtlMoveMemory", Ptr, pData, Ptr,&Buffer, UInt,nSize )
	DllCall( "GlobalUnlock", Ptr, hData )
	DllCall( "ole32\CreateStreamOnHGlobal", Ptr, hData, Int, True, PtrP, pStream )
	DllCall( "LoadLibrary", Str,"gdiplus" )
	VarSetCapacity(si, 16, 0), si := Chr(1)
	DllCall( "gdiplus\GdiplusStartup", PtrP, pToken, Ptr, &si, UInt,0 )
	DllCall( "gdiplus\GdipCreateBitmapFromStream", Ptr, pStream, PtrP, pBitmap )
	DllCall( "gdiplus\GdipCreateHBITMAPFromBitmap", Ptr,pBitmap, PtrP, hBitmap, UInt,0)
	
	hNewBitMap := DllCall("CopyImage"
		  , Ptr, hBitmap
		  , UInt, 0
		  , Int, width
		  , Int, height
		  , UInt, 0x00000008      ;LR_COPYDELETEORG
		  , Ptr) 
	  
	DllCall( "gdiplus\GdipDisposeImage", Ptr, pBitmap )
	DllCall( "gdiplus\GdiplusShutdown", Ptr, pToken )
	DllCall( NumGet(NumGet(1*pStream)+8), Ptr, pStream )
	
	Return hNewBitMap
}
LoadScriptResource(ByRef Data,Name, Type = 10)
{
   ; originally posted by Lexikos, modified by HotKeyIt
   ; http://www.autohotkey.com/forum/post-516086.html#516086

    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")
    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")
    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")
    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")
    VarSetCapacity(Data,DataSize)
    DllCall("RtlMoveMemory","PTR",&Data,"PTR",DllCall("LockResource", "ptr", hresdata, "ptr"),"UInt",DataSize)
    return DataSize
} 
FileInstall, .\sample.png, ~