[Gdip] Use Base64 PNG data with Gdip? Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

[Gdip] Use Base64 PNG data with Gdip?

30 May 2018, 12:08

How do I use Base64 encoded PNG image data with Gdip?

I'm currently using Gdip_CreateBitmapFromFile() to load an external PNG image file.

I know how to encode the image file and get the Base64 encoded string, and decode to raw binary data stored in memory, but I don't know how to use the data with Gdip functions without having to first save the data to a file. I want to keep the image data in memory without the need of an external file.

Any ideas? Thank you!

Edit: I found the following code which works, but I'm not sure if it's the best solution since my image technically isn't an icon (don't know if that matters... 480x32px), so I'm still open to suggestions. Thanks!

Code: Select all

MyImageHICON := base64_to_hicon(Base64Data)
	
MyImageBMAP := Gdip_CreateBitmapFromHICON(MyImageHICON)

base64_to_hicon(base64) { ; Modified from just me's ImageToInclude
  hBitmap := 0
  VarSetCapacity(B64, StrLen(base64) << !!A_IsUnicode)
  B64 := base64
  If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
     Return False
  VarSetCapacity(Dec, DecLen, 0)
  If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
     Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
  pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
  DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
  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\GdipCreateHICONFromBitmap", "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
}
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
tmplinshi
Posts: 1561
Joined: 01 Oct 2013, 14:57

Re: [Gdip] Use Base64 PNG data with Gdip?

30 May 2018, 18:50

just me's ImageToInclude can convert image to HICON or HBITMAP.

Just replace GdipCreateHICONFromBitmap with GdipCreateHBITMAPFromBitmap in your code, and use Gdip_CreateBitmapFromHBITMAP instead.

Code: Select all

MyImageHBMP := base64_to_hbmp(Base64Data)
	
MyImageBMAP := Gdip_CreateBitmapFromHBITMAP(MyImageHBMP)

base64_to_hbmp(ByRef base64) { ; Modified from just me's ImageToInclude
  hBitmap := 0
  VarSetCapacity(B64, StrLen(base64) << !!A_IsUnicode)
  B64 := base64
  If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
     Return False
  VarSetCapacity(Dec, DecLen, 0)
  If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
     Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
  pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
  DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
  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
}
tmplinshi
Posts: 1561
Joined: 01 Oct 2013, 14:57

Re: [Gdip] Use Base64 PNG data with Gdip?

30 May 2018, 18:58

base64_to_hbmp(ByRef base64)
ByRef should be used here, according to the doc:
When passing large strings to a function, ByRef enhances performance and conserves memory by avoiding the need to make a copy of the string. Similarly, using ByRef to send a long string back to the caller usually performs better than something like Return HugeString.
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

30 May 2018, 19:07

tmplinshi wrote:base64_to_hbmp(ByRef base64) ByRef should be used here, according to the doc
I think the original function I found did use ByRef and I removed it. I wasn't aware of the performance gain. Thanks for letting me know.

Working on my first AutoHotkey game using Gdip rather than manipulating picture controls, etc. Should have learned to use Gdip much sooner! :)
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

30 May 2018, 21:17

I just realized that my PNG transparency is lost using the suggestions from tmplinshi. Using as HICON preserves the transparency in my tests.

Is there any negative side effects to using HICON handle for larger images that are not icons?
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
nnnik
Posts: 4461
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 03:51

This function is not the answer due to several reasons:

First the function binds the base64 data to binary then turns it into a stream.
Afterwads it turns this stream into a pBitmap - yeah at this point you already have your pBitmap.
Then it turns your pBitmap into a hBitmap (loosing a lot of stuff like transperency etc.)
Finally it returns your hBitmap and you now suggest turning this hBitmap into a pBitmap.

But thats not the worst part of it.
When he is doing all that he loads and unloads GDIp meaning that if you use any of his functions you have to startup GDIp again:

Code: Select all

#Include <gdip_all> ;or any other GDIp version

pToken := Gdip_Startup()
base64Image := "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"
hImage := base64_to_hbmp(base64Image)
pBitmap := Gdip_CreateBitmapFromHICON(hImage) ;will fail because it is neither a hBitmap nor is GDIp initialized
Msgbox % myImageBMP . "`n" . ErrorLevel . "`n" . A_LastError

base64_to_hbmp(ByRef base64) { ; Modified from just me's ImageToInclude
	hBitmap := 0
	VarSetCapacity(B64, StrLen(base64) << !!A_IsUnicode)
	B64 := base64
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	VarSetCapacity(Dec, DecLen, 0)
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
	hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
	pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
	DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
	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
}
A shorter version of his code will already do everything you want without side effects.

Code: Select all

GDIp_BitmapFromBase64(base64) { ; Modified from just me's ImageToInclude and tmplinshis base64_to_hbmp 
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	VarSetCapacity(Dec, DecLen, 0)
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  ;modified by nnnik to return a pBitmap instead
	hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
	pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
	DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
	DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM",  "Ptr", pStream, "PtrP", pBitmap)
	Return pBitmap
}
Recommends AHK Studio
just me
Posts: 7114
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 04:11

nnnik wrote:A shorter version of his code will already do everything you want without side effects.
Don't forget to release IStream.
Also, SHCreateMemStream() would make the function even shorter. (I didn't know it when I wrote my original function).
User avatar
nnnik
Posts: 4461
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 07:21

Hmm yeah I might just do that since I have some free time.

Code: Select all

GDIp_BitmapFromBase64(byref base64) { ; Modified from just me's ImageToInclude and tmplinshis base64_to_hbmp 
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	VarSetCapacity(Dec, DecLen, 0)
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  ;modified by nnnik to return a pBitmap instead
	pStream := DllCall("shwlapi\SHCreateMemStream", Ptr, &Dec, UInt, DecLen) ;might have a Cdecl calling convention
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM",  "Ptr", pStream, "PtrP", pBitmap)
	Release := NumGet( NumGet( pStream+0 ), 2*A_PtrSize) 
	DllCall(Release, Ptr, pStream) 
	Return pBitmap
}
Recommends AHK Studio
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 07:42

nnnik wrote:Hmm yeah I might just do that since I have some free time.

Code: Select all

GDIp_BitmapFromBase64(byref base64) { ; Modified from just me's ImageToInclude and tmplinshis base64_to_hbmp 
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
	VarSetCapacity(Dec, DecLen, 0)
	If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &base64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)
		Return False
  ; Bitmap creation adopted from "How to convert Image data (JPEG/PNG/GIF) to hBITMAP?" by SKAN
  ; -> http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
  ;modified by nnnik to return a pBitmap instead
	pStream := DllCall("shwlapi\SHCreateMemStream", Ptr, &Dec, UInt, DecLen) ;might have a Cdecl calling convention
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM",  "Ptr", pStream, "PtrP", pBitmap)
	Release := NumGet( NumGet( pStream+0 ), 2*A_PtrSize) 
	DllCall(Release, Ptr, pStream) 
	Return pBitmap
}
I don't understand how to get the code with GdipCreateBitmapFromStreamICM to work with DrawImage. Your earlier shortened code works fine however (where you wrote "A shorter version of his code will already do everything you want without side effects."). Any ideas?
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
nnnik
Posts: 4461
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 07:47

Yeah this code is untested might have some bugs and I wrote it using my phone. I will get around to fix it but not today.
Recommends AHK Studio
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 07:54

nnnik wrote:Yeah this code is untested might have some bugs and I wrote it using my phone. I will get around to fix it but not today.
I found the error and corrected it.

pStream := DllCall("shwlapi\SHCreateMemStream", Ptr, &Dec, UInt, DecLen)

It is misspelled.

This works:
pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &Dec, "UInt", DecLen)

Thank you all so much for your help!
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
just me
Posts: 7114
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Gdip] Use Base64 PNG data with Gdip?

31 May 2018, 08:04

Code: Select all

	Release := NumGet( NumGet( pStream+0 ), 2*A_PtrSize) 
	DllCall(Release, Ptr, pStream)
might be replaced with

Code: Select all

	ObjRelease(pStream)
Also, I'd use

Code: Select all

	pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &Dec, "UInt", DecLen, "UPtr") ; the return value is a pointer
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?  Topic is solved

31 May 2018, 09:08

Thank you again! I modified the function to handle HBITMAP and HICON:

Code: Select all

GdipCreateFromBase64(pIcon16, true) ; 16x16 Base64 encoded PNG image string returned as HICON
GdipCreateFromBase64(pMyLargerImage) ; 640x384 Base64 encoded PNG image string returned as HBITMAP

Code: Select all

GdipCreateFromBase64(ByRef Base64, HICON := 0) {
	If (!DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &Base64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)) {
		return False
	}

	VarSetCapacity(Dec, DecLen, 0)

	If (!DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &Base64, "UInt", 0, "UInt", 0x01, "Ptr", &Dec, "UIntP", DecLen, "Ptr", 0, "Ptr", 0)) {
		return False
	}

	pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &Dec, "UInt", DecLen, "UPtr")
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM", "Ptr", pStream, "PtrP", pBitmap)

	If (HICON) {
		DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
	}

	ObjRelease(pStream)

	return (HICON ? hBitmap : pBitmap)
}
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
swagfag
Posts: 3768
Joined: 11 Jan 2017, 17:59

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 12:44

TheDewd wrote:
31 May 2018, 09:08
Spoiler
it would be cool if this could be included in the gdip lib
https://github.com/mmikeww/AHKv2-Gdip/b ... ip_All.ahk
SOTE
Posts: 1021
Joined: 15 Jun 2015, 06:21

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 13:11

Would also be nice to show this as an example script of it being used. Lots of fragments and corrections of code, versus clear example.
Last edited by SOTE on 29 Nov 2018, 14:08, edited 1 time in total.
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 13:16

SOTE wrote:
29 Nov 2018, 13:11
Would also be nice to show this as an example script of it being used.
I used this in my Bulldozer game project. See https://autohotkey.com/boards/viewtopic.php?f=6&t=50139

Script with no external images.
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
SOTE
Posts: 1021
Joined: 15 Jun 2015, 06:21

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 14:05

TheDewd wrote:
29 Nov 2018, 13:16
SOTE wrote:
29 Nov 2018, 13:11
Would also be nice to show this as an example script of it being used.
I used this in my Bulldozer game project. See https://autohotkey.com/boards/viewtopic.php?f=6&t=50139

Script with no external images.
Nice! Fun game and good example script, by the way.
User avatar
TheDewd
Posts: 1391
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 15:47

I modified the function for a new project so that I can assign the images to a Picture control.

The previous function will return the pBitmap pointer, but I added an extra DllCall to convert pBitmap to hBitmap.

See example below:

Code: Select all

#SingleInstance, Force

B64Logo := "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"

; GDI+ Startup
hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll") ; Load module
VarSetCapacity(GdiplusStartupInput, (A_PtrSize = 8 ? 24 : 16), 0) ; GdiplusStartupInput structure
NumPut(1, GdiplusStartupInput, 0, "UInt") ; GdiplusVersion
VarSetCapacity(pToken, 0)
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0) ; Initialize GDI+

BMPLogo := GdipCreateFromBase64(B64Logo)

; Free GDI+ module from memory
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)

Gui, +LastFound -Resize
Gui, Margin, 0, 0
Gui, Add, Picture, x0 y0 w517 h78, % "HBITMAP:*" BMPLogo
Gui, Show, AutoSize, Example
return

GdipCreateFromBase64(B64, IsIcon := 0) {
	VarSetCapacity(B64Len, 0)
	DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", StrLen(B64), "UInt", 0x01, "Ptr", 0, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
	VarSetCapacity(B64Dec, B64Len, 0) ; pbBinary size
	DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &B64, "UInt", StrLen(B64), "UInt", 0x01, "Ptr", &B64Dec, "UIntP", B64Len, "Ptr", 0, "Ptr", 0)
	pStream := DllCall("Shlwapi.dll\SHCreateMemStream", "Ptr", &B64Dec, "UInt", B64Len, "UPtr")
	VarSetCapacity(pBitmap, 0)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStreamICM", "Ptr", pStream, "PtrP", pBitmap)
	VarSetCapacity(hBitmap, 0)
	DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap, "UInt*", hBitmap, "Int", 0XFFFFFFFF)

	If (IsIcon) {
		DllCall("Gdiplus.dll\GdipCreateHICONFromBitmap", "Ptr", pBitmap, "PtrP", hIcon, "UInt", 0)
	}

	ObjRelease(pStream)
	return (IsIcon ? hIcon : hBitmap)
}
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
guest3456
Posts: 3112
Joined: 09 Oct 2013, 10:31

Re: [Gdip] Use Base64 PNG data with Gdip?

29 Nov 2018, 23:30

swagfag wrote:
29 Nov 2018, 12:44
it would be cool if this could be included in the gdip lib
https://github.com/mmikeww/AHKv2-Gdip/b ... ip_All.ahk
i'll happily accept a pull request. i think we need some documentation within the func on how to create the base64 string to begin with (i saw a SKAN link earlier up in this thread?). or could even add a new Example file too to the lib

and i'm not sure if just a boolean param at the end is sufficient for return type. seems like TheDewd now has ways to return either HICON, hBitmap, or pBitmap. do we want all those options? i argue no. i think it should just return the pBitmap and be named "Gdip_CreatBitmapFromBase64()" for consistency. because, the lib already has the wrapper funcs to convert a pBitmap into an hBitmap or hIcon that the user can simply nest the funcs on top of each other if they need those other formats. most of the lib works with simply pBitmaps


Return to “Ask For Help”

Who is online

Users browsing this forum: aifritz, euras, Google [Bot] and 242 guests