svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

Post your working scripts, libraries and tools.
MrDoge
Posts: 161
Joined: 27 Apr 2020, 21:29

svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

27 Sep 2023, 07:14

(since AddPicture() can't add an SVG)

svgToHBITMAP.ah2

Code: Select all

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

svgToHBITMAP(svgPath,width,height) {
	;https://gist.github.com/smourier/5b770d32043121d477a8079ef6be0995
	;https://stackoverflow.com/questions/75917247/convert-svg-files-to-bitmap-using-direct2d-in-mfc#75935717
	; ID2D1DeviceContext5::CreateSvgDocument is the carrying api
	hModule:=DllCall("GetModuleHandleA","AStr","WindowsCodecs.dll","Ptr")||DllCall("LoadLibraryA","AStr","WindowsCodecs.dll","Ptr")
	CLSID_WICImagingFactory:=Buffer(0x10)
	NumPut("UInt64",0x433D5F24317D06E8,CLSID_WICImagingFactory,0x0)
	NumPut("UInt64",0xC2ABD868CE79F7BD,CLSID_WICImagingFactory,0x8)
	IID_IClassFactory:=Buffer(0x10)
	NumPut("UInt64",0x0000000000000001,IID_IClassFactory,0x0)
	NumPut("UInt64",0x46000000000000C0,IID_IClassFactory,0x8)
	DllGetClassObject:=DllCall("GetProcAddress","Ptr",hModule,"AStr","DllGetClassObject","Ptr")
	DllCall(DllGetClassObject,"Ptr",CLSID_WICImagingFactory,"Ptr",IID_IClassFactory,"Ptr*",&IClassFactory:=0)

	IID_IWICImagingFactory:=Buffer(0x10)
	NumPut("UInt64",0x4314C395EC5EC8A9,IID_IWICImagingFactory,0x0)
	NumPut("UInt64",0x70FF35A9D754779C,IID_IWICImagingFactory,0x8)
	ComCall(3,IClassFactory,"Ptr",0,"Ptr",IID_IWICImagingFactory,"Ptr*",&IWICImagingFactory:=0) ;HRESULT IClassFactory::CreateInstance(IUnknown *pUnkOuter,REFIID riid,void **ppvObject)

	GUID_WICPixelFormat32bppPBGRA:=Buffer(0x10)
	NumPut("UInt64",0x4BFE4E036FDDC324,GUID_WICPixelFormat32bppPBGRA,0x0)
	NumPut("UInt64",0x10C98D76773D85B1,GUID_WICPixelFormat32bppPBGRA,0x8)
	ComCall(17,IWICImagingFactory,"Uint",width,"Uint",height,"Ptr",GUID_WICPixelFormat32bppPBGRA,"Int",0x2,"Ptr*",&IWICBitmap:=0) ;HRESULT IWICImagingFactory::CreateBitmap(UINT uiWidth,UINT uiHeight,REFWICPixelFormatGUID pixelFormat,WICBitmapCreateCacheOption option,IWICBitmap **ppIBitmap); 0x2=WICBitmapCacheOnLoad


	IID_ID2D1Factory:=Buffer(0x10)
	NumPut("UInt64",0x465A6F5006152247,IID_ID2D1Factory,0x0)
	NumPut("UInt64",0x07603BFD8B114592,IID_ID2D1Factory,0x8)

	DllCall("GetModuleHandleA", "AStr", "d2d1") || DllCall("LoadLibraryA", "AStr", "d2d1") ;this is needed to avoid "Critical Error: Invalid memory read/write"
	DllCall("d2d1\D2D1CreateFactory","Int",0,"Ptr",IID_ID2D1Factory,"Ptr",0,"Ptr*",&ID2D1Factory:=0) ;Int 0=D2D1_FACTORY_TYPE_SINGLE_THREADED

	D2D1_RENDER_TARGET_PROPERTIES:=Buffer(0x1c,0)
	ComCall(13,ID2D1Factory,"Ptr",IWICBitmap,"Ptr",D2D1_RENDER_TARGET_PROPERTIES,"Ptr*",&ID2D1RenderTarget:=0) ;HRESULT ID2D1Factory::CreateWicBitmapRenderTarget(IWICBitmap *target,D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties,ID2D1RenderTarget **renderTarget)

	; IID_ID2D1DeviceContext5:=Buffer(0x10)
	; NumPut("UInt64",0x4DF668CC7836D248,IID_ID2D1DeviceContext5,0x0)
	; NumPut("UInt64",0xB72EF61B99DEE8B9,IID_ID2D1DeviceContext5,0x8)
	; ComCall(0,ID2D1RenderTarget,"Ptr",IID_ID2D1DeviceContext5,"Ptr*",&ID2D1DeviceContext5:=0) ;HRESULT ID2D1RenderTarget::QueryInterface(REFIID riid,void **ppvObject)

	DllCall("shlwapi\SHCreateStreamOnFileW","WStr",svgPath,"Uint",0,"Ptr*",&IStream:=0)

	D2D1_SIZE_F:=Buffer(8)
	NumPut("float",width,D2D1_SIZE_F,0x0)
	NumPut("float",height,D2D1_SIZE_F,0x4)
	ComCall(115,ID2D1RenderTarget,"Ptr",IStream,"Uint64",NumGet(D2D1_SIZE_F,"Uint64"),"Ptr*",&ID2D1SvgDocument:=0) ;HRESULT ID2D1DeviceContext5::CreateSvgDocument(IStream *inputXmlStream,D2D1_SIZE_F viewportSize,ID2D1SvgDocument **svgDocument)

	ComCall(48,ID2D1RenderTarget,"int") ;void ID2D1RenderTarget::BeginDraw()
	ComCall(116,ID2D1RenderTarget,"Ptr",ID2D1SvgDocument,"int") ;void ID2D1DeviceContext5::DrawSvgDocument(ID2D1SvgDocument *svgDocument)
	ComCall(49,ID2D1RenderTarget,"Ptr",0,"Ptr",0) ;HRESULT ID2D1RenderTarget::EndDraw(D2D1_TAG *tag1,D2D1_TAG *tag2)

	cbStride:=4*width ;stride=bpp*width
	pData:=Buffer(cbStride * height) ;bpp*width*height
	ComCall(7,IWICBitmap,"Ptr",0,"Uint",cbStride,"Uint",pData.Size,"Ptr",pData) ;HRESULT IWICBitmapSource::CopyPixels(WICRect *prc,UINT cbStride,UINT cbBufferSize,BYTE *pbBuffer)

	HBITMAP := DllCall("gdi32\CreateBitmap","Int",width,"Int",height,"Uint",1,"Uint",32,"Ptr",pData,"Ptr")
	return HBITMAP
}
myGui:=Gui()
myGui.AddPicture(,"HBITMAP:" svgToHBITMAP("C:\windows.refresh.svg",800,800))
myGui.Show()

return

f3::Exitapp
for those interested, here is a C version converted from the cpp original

SaveWicSvgToPng.c

Code: Select all

#include <windows.h>
#include "shlwapi.h"
#include "d2d1.h"
#include "d2d1_3.h" // ID2D1DeviceContext5
#include "wincodec.h" // Wic

#pragma comment(lib, "shlwapi")
#pragma comment(lib, "ole32")
#pragma comment(lib, "d2d1")

typedef struct ID2D1FactoryVtbl
{
	void * lol[13];
	STDMETHOD(CreateWicBitmapRenderTarget)(
		__RPC__in ID2D1Factory * This,
		_In_ IWICBitmap *target,
		_In_ CONST D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties,
		_COM_Outptr_ ID2D1RenderTarget **renderTarget
		) PURE;
} ID2D1FactoryVtbl;

interface ID2D1Factory
{
	CONST_VTBL struct ID2D1FactoryVtbl *lpVtbl;
};

typedef interface ID2D1DeviceContext5 ID2D1DeviceContext5;

typedef struct ID2D1DeviceContext5Vtbl
{
	void * lol0[48];
	STDMETHOD_(void, BeginDraw)(
		__RPC__in ID2D1DeviceContext5 * This
		) PURE;
	STDMETHOD(EndDraw)(
		__RPC__in ID2D1DeviceContext5 * This,
		_Out_opt_ D2D1_TAG *tag1 = NULL,
		_Out_opt_ D2D1_TAG *tag2 = NULL
		) PURE;
	void * lol1[65];
	STDMETHOD(CreateSvgDocument)(
		__RPC__in ID2D1DeviceContext5 * This,
		_In_opt_ IStream *inputXmlStream,
		D2D1_SIZE_F viewportSize,
		_COM_Outptr_ ID2D1SvgDocument **svgDocument
		) PURE;
	STDMETHOD_(void, DrawSvgDocument)(
		__RPC__in ID2D1DeviceContext5 * This,
		_In_ ID2D1SvgDocument *svgDocument
		) PURE;
} ID2D1DeviceContext5Vtbl;

interface ID2D1DeviceContext5
{
	CONST_VTBL struct ID2D1DeviceContext5Vtbl *lpVtbl;
};

void SaveSvgAsPng(LPCWSTR input_SVG, LPCWSTR output_PNG, UINT width, UINT height)
{
	//https://gist.github.com/smourier/5b770d32043121d477a8079ef6be0995
	//https://stackoverflow.com/questions/75917247/convert-svg-files-to-bitmap-using-direct2d-in-mfc#75935717
	// ID2D1DeviceContext5::CreateSvgDocument is the carrying api
	HMODULE hModule = LoadLibraryA("WindowsCodecs.dll");
	typeof(DllGetClassObject) *proc_DllGetClassObject = (typeof(DllGetClassObject)*)GetProcAddress(hModule,"DllGetClassObject");
	IClassFactory *pIClassFactory;
	proc_DllGetClassObject(&CLSID_WICImagingFactory,&IID_IClassFactory,(void**)&pIClassFactory);

	GUID IID_IWICImagingFactory = {0xec5ec8a9,0xc395, 0x4314, 0x9c, 0x77, 0x54, 0xd7, 0xa9, 0x35, 0xff, 0x70};
	IWICImagingFactory *pIWICImagingFactory;
	pIClassFactory->lpVtbl->CreateInstance(pIClassFactory,0,&IID_IWICImagingFactory,(void**)&pIWICImagingFactory);

	IWICBitmap *pIWICBitmap;
	pIWICImagingFactory->lpVtbl->CreateBitmap(pIWICImagingFactory,width,height,&GUID_WICPixelFormat32bppPBGRA,WICBitmapCacheOnLoad,&pIWICBitmap);

	// initialize Direct2D
	ID2D1Factory *pID2D1Factory;
	D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, 0, (void**)&pID2D1Factory);

	D2D1_RENDER_TARGET_PROPERTIES pD2D1_RENDER_TARGET_PROPERTIES = {0,0,0,0,0,0};
	//skipping ID2D1RenderTarget::QueryInterface to ID2D1DeviceContext5
	ID2D1DeviceContext5 *pID2D1DeviceContext5;
	pID2D1Factory->lpVtbl->CreateWicBitmapRenderTarget(pID2D1Factory,pIWICBitmap,&pD2D1_RENDER_TARGET_PROPERTIES,(ID2D1RenderTarget**)&pID2D1DeviceContext5);

	IStream *pIStream;
	SHCreateStreamOnFileW(input_SVG,0,&pIStream);

	D2D1_SIZE_F pD2D1_SIZE_F = { (float)width, (float)height };
	ID2D1SvgDocument *pID2D1SvgDocument;
	pID2D1DeviceContext5->lpVtbl->CreateSvgDocument(pID2D1DeviceContext5,pIStream,pD2D1_SIZE_F,&pID2D1SvgDocument); //ID2D1DeviceContext5::CreateSvgDocument

	pID2D1DeviceContext5->lpVtbl->BeginDraw(pID2D1DeviceContext5); //ID2D1RenderTarget::BeginDraw
	pID2D1DeviceContext5->lpVtbl->DrawSvgDocument(pID2D1DeviceContext5,pID2D1SvgDocument); //ID2D1DeviceContext5::DrawSvgDocument
	pID2D1DeviceContext5->lpVtbl->EndDraw(pID2D1DeviceContext5,0,0); //ID2D1RenderTarget::EndDraw

	// create PNG file
	IWICStream *pIWICStream;
	pIWICImagingFactory->lpVtbl->CreateStream(pIWICImagingFactory,&pIWICStream);
	pIWICStream->lpVtbl->InitializeFromFilename(pIWICStream,output_PNG,GENERIC_WRITE);

	// create PNG encoder
	IWICBitmapEncoder *pIWICBitmapEncoder;
	pIWICImagingFactory->lpVtbl->CreateEncoder(pIWICImagingFactory,&GUID_ContainerFormatPng,0,&pIWICBitmapEncoder);
	pIWICBitmapEncoder->lpVtbl->Initialize(pIWICBitmapEncoder,(IStream*)pIWICStream,WICBitmapEncoderNoCache);

	// create frame
	IWICBitmapFrameEncode *pIWICBitmapFrameEncode;
	pIWICBitmapEncoder->lpVtbl->CreateNewFrame(pIWICBitmapEncoder,&pIWICBitmapFrameEncode,0);
	pIWICBitmapFrameEncode->lpVtbl->Initialize(pIWICBitmapFrameEncode,0);

	// write bitmap
	pIWICBitmapFrameEncode->lpVtbl->WriteSource(pIWICBitmapFrameEncode,(IWICBitmapSource*)pIWICBitmap,0);

	// commit
	pIWICBitmapFrameEncode->lpVtbl->Commit(pIWICBitmapFrameEncode);
	pIWICBitmapEncoder->lpVtbl->Commit(pIWICBitmapEncoder);
}

int main()
{
	CoInitialize(0);
	SaveSvgAsPng(L"C:\\windows.refresh.svg",L"drawing.png",800, 800);
	CoUninitialize();
	return 0;
}
edit: Thanks to @iPhilip for pointing out void BeginDraw();
Last edited by MrDoge on 11 Apr 2024, 22:56, edited 1 time in total.
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

27 Sep 2023, 10:54

Hmmm... Could your code be a bit shorter / more efficient using built-in AHK functions?

Code: Select all

      ; Initialize Windows Imaging Component.
      IWICImagingFactory := ComObject(CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}", IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}")

      ; WICBitmapNoCache  must be 1!
      ; IWICImagingFactory::CreateBitmap - https://github.com/iseahound/10/blob/win/10.0.16299.0/um/wincodec.h#L6447
      DllCall("ole32\CLSIDFromString", "wstr", GUID_WICPixelFormat32bppBGRA := "{6fddc324-4e03-4bfe-b185-3d77768dc90f}", "ptr", CLSID := Buffer(16), "hresult")
      ComCall(17, IWICImagingFactory, "uint", width, "uint", height, "ptr", CLSID, "int", 1, "ptr*", &wicBitmap:=0)
This is what I use, I think it's the same thing!
https://github.com/iseahound/ImagePut/blob/9ef0dfce751e0626ee75ae38f66f650534132089/ImagePut.ahk#L4021

Great work! 👍
MrDoge
Posts: 161
Joined: 27 Apr 2020, 21:29

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

28 Sep 2023, 09:18

iseahound wrote:
27 Sep 2023, 10:54
This is what I use, I think it's the same thing!
https://github.com/iseahound/ImagePut/blob/9ef0dfce751e0626ee75ae38f66f650534132089/ImagePut.ahk#L4021
I went in your code and I couldn't find the string "svg" nor the string "116"
I was scared you had already implemented it
iseahound wrote:
27 Sep 2023, 10:54
Hmmm... Could your code be a bit shorter / more efficient using built-in AHK functions?
I will code it in your style, (I prefer the way I code it(I call it theoretical), even if it's longer, the solution is: I keep my code, you keep your copy)

Code: Select all

#SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.

svgToHBITMAP(svgPath,width,height) {
	;https://gist.github.com/smourier/5b770d32043121d477a8079ef6be0995
	;https://stackoverflow.com/questions/75917247/convert-svg-files-to-bitmap-using-direct2d-in-mfc#75935717
	; ID2D1DeviceContext5::CreateSvgDocument is the carrying api
	IWICImagingFactory:=ComObject("{317d06e8-5f24-433d-bdf7-79ce68d8abc2}","{ec5ec8a9-c395-4314-9c77-54d7a935ff70}")

	; I get an error when using ((GUID_WICPixelFormat32bppPBGRA instead of GUID_WICPixelFormat32bppBGRA) && (0x1=WICBitmapNoCache instead of 0x2=WICBitmapCacheOnLoad))
	; Error: An exception was thrown. Specifically: 0x80000003 ▶ ComCall(13,ID2D1Factory,"Ptr",IWICBitmap,"Ptr",D2D1_RENDER_TARGET_PROPERTIES,"Ptr*",&ID2D1RenderTarget:=0)
	; but I won't try to understand why I get an error..
	; DllCall("ole32\CLSIDFromString","WStr","{6fddc324-4e03-4bfe-b185-3d77768dc90f}","Ptr",GUID_WICPixelFormat32bppBGRA:=Buffer(16))
	; ComCall(17,IWICImagingFactory,"Uint",width,"Uint",height,"Ptr",GUID_WICPixelFormat32bppBGRA,"Int",0x1,"Ptr*",&IWICBitmap:=0) ;IWICImagingFactory::CreateBitmap, 0x1=WICBitmapNoCache

	DllCall("ole32\CLSIDFromString","WStr","{6fddc324-4e03-4bfe-b185-3d77768dc910}","Ptr",GUID_WICPixelFormat32bppPBGRA:=Buffer(16))
	ComCall(17,IWICImagingFactory,"Uint",width,"Uint",height,"Ptr",GUID_WICPixelFormat32bppPBGRA,"Int",0x2,"Ptr*",&IWICBitmap:=0) ;HRESULT IWICImagingFactory::CreateBitmap(UINT uiWidth,UINT uiHeight,REFWICPixelFormatGUID pixelFormat,WICBitmapCreateCacheOption option,IWICBitmap **ppIBitmap); 0x2=WICBitmapCacheOnLoad


	DllCall("ole32\CLSIDFromString","WStr","{06152247-6f50-465a-9245-118bfd3b6007}","Ptr",IID_ID2D1Factory:=Buffer(16))
	DllCall("GetModuleHandleA", "AStr", "d2d1") || DllCall("LoadLibraryA", "AStr", "d2d1") ;this is needed to avoid "Critical Error: Invalid memory read/write"
	DllCall("d2d1\D2D1CreateFactory","Int",0,"Ptr",IID_ID2D1Factory,"Ptr",0,"Ptr*",&ID2D1Factory:=0) ;Int 0=D2D1_FACTORY_TYPE_SINGLE_THREADED

	D2D1_RENDER_TARGET_PROPERTIES:=Buffer(0x1c,0)
	ComCall(13,ID2D1Factory,"Ptr",IWICBitmap,"Ptr",D2D1_RENDER_TARGET_PROPERTIES,"Ptr*",&ID2D1RenderTarget:=0) ;HRESULT ID2D1Factory::CreateWicBitmapRenderTarget(IWICBitmap *target,D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties,ID2D1RenderTarget **renderTarget)

	; DllCall("ole32\CLSIDFromString","WStr","{7836d248-68cc-4df6-b9e8-de991bf62eb7}","Ptr",IID_ID2D1DeviceContext5:=Buffer(16))
	; ComCall(0,ID2D1RenderTarget,"Ptr",IID_ID2D1DeviceContext5,"Ptr*",&ID2D1DeviceContext5:=0) ;ID2D1RenderTarget::QueryInterface

	DllCall("shlwapi\SHCreateStreamOnFileW","WStr",svgPath,"Uint",0,"Ptr*",&IStream:=0)

	D2D1_SIZE_F:=Buffer(8)
	NumPut("float",width,D2D1_SIZE_F,0x0)
	NumPut("float",height,D2D1_SIZE_F,0x4)
	ComCall(115,ID2D1RenderTarget,"Ptr",IStream,"Uint64",NumGet(D2D1_SIZE_F,"Uint64"),"Ptr*",&ID2D1SvgDocument:=0) ;HRESULT ID2D1DeviceContext5::CreateSvgDocument(IStream *inputXmlStream,D2D1_SIZE_F viewportSize,ID2D1SvgDocument **svgDocument)

	ComCall(48,ID2D1RenderTarget,"int") ;void ID2D1RenderTarget::BeginDraw()
	ComCall(116,ID2D1RenderTarget,"Ptr",ID2D1SvgDocument,"int") ;void ID2D1DeviceContext5::DrawSvgDocument(ID2D1SvgDocument *svgDocument)
	ComCall(49,ID2D1RenderTarget,"Ptr",0,"Ptr",0) ;HRESULT ID2D1RenderTarget::EndDraw(D2D1_TAG *tag1,D2D1_TAG *tag2)

	cbStride:=4*width ;stride=bpp*width
	pData:=Buffer(cbStride * height) ;bpp*width*height
	ComCall(7,IWICBitmap,"Ptr",0,"Uint",cbStride,"Uint",pData.Size,"Ptr",pData) ;HRESULT IWICBitmapSource::CopyPixels(WICRect *prc,UINT cbStride,UINT cbBufferSize,BYTE *pbBuffer)

	HBITMAP := DllCall("gdi32\CreateBitmap","Int",width,"Int",height,"Uint",1,"Uint",32,"Ptr",pData,"Ptr")
	return HBITMAP
}
myGui:=Gui()
myGui.AddPicture(,"HBITMAP:" svgToHBITMAP("C:\windows.refresh.svg",800,800))
myGui.Show()

return

f3::Exitapp
the only tricks I used were ComObject and ole32\CLSIDFromString, if I missed any, tell me

; I get an error when using ((GUID_WICPixelFormat32bppPBGRA instead of GUID_WICPixelFormat32bppBGRA) && (0x1=WICBitmapNoCache instead of 0x2=WICBitmapCacheOnLoad))
; Error: An exception was thrown. Specifically: 0x80000003 ▶ ComCall(13,ID2D1Factory,"Ptr",IWICBitmap,"Ptr",D2D1_RENDER_TARGET_PROPERTIES,"Ptr*",&ID2D1RenderTarget:=0)
; but I won't try to understand why I get an error..
; DllCall("ole32\CLSIDFromString","WStr","{6fddc324-4e03-4bfe-b185-3d77768dc90f}","Ptr",GUID_WICPixelFormat32bppBGRA:=Buffer(16))
; ComCall(17,IWICImagingFactory,"Uint",width,"Uint",height,"Ptr",GUID_WICPixelFormat32bppBGRA,"Int",0x1,"Ptr*",&IWICBitmap:=0) ;IWICImagingFactory::CreateBitmap, 0x1=WICBitmapNoCache
maybe, just maybe, you do understand this : is it the difference between GUID_WICPixelFormat32bppBGRA and GUID_WICPixelFormat32bppPBGRA ?
Last edited by MrDoge on 11 Apr 2024, 23:00, edited 1 time in total.
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

28 Sep 2023, 09:25

Oh I liked your style — I just thought you could condense the code a bit using ComObject
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

24 Feb 2024, 10:21

@MrDoge Do you mind if I add your code to my project to ImagePut? There will be some modifications and I will give you credit.
MrDoge
Posts: 161
Joined: 27 Apr 2020, 21:29

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

24 Feb 2024, 14:53

@iseahound
If you're asking do I mind: You can omit the credits if you want, I don't care (and idk when I'll care)
modifications: sure, do what you want, do what you need
do I like seeing credits: sure

If you're notifying me: cool that it's used by you, and ImagePut
also: cool that it's actually used, especially a project/script I forgot about, a treat
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

24 Feb 2024, 15:54

Thanks! I figure since I'm refactoring ImagePut anyways, I'd throw in as many features as possible. It should end up kind of like a unified library for images, kind of like pillow. I really appreciate your script, it's not something I could have done myself.
robodesign
Posts: 934
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

03 Mar 2024, 17:49

@MrDoge .and @iseahound. I would like to add support for SVGs, Heic and Avif image files in my image viewer /editor (QPV) . Is it okay if I inspire myself or re-use and adapt functions you guys wrote? I will give credits to you guys.

Thank you in advance.

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

11 Apr 2024, 14:56

@MrDoge This code seems to be a little unstable as of the latest version 11. I kept getting errors on the BeginDraw line and after I installed the Windows SDK it seemed to go away. I'm well aware Microsoft changes the ordinals occasionally but It seems that BeginDraw is still at Ordinal 48 so that's not a problem. Any ideas? Whatever bug is inherent here is hard to reproduce.
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

11 Apr 2024, 15:16

Changing the following line to use the nullptr @ the 3rd parameter

Code: Select all

DllCall("d2d1\D2D1CreateFactory","Int",0,"Ptr",IID_ID2D1Factory,"ptr",0,"Ptr*",&ID2D1Factory:=0, "hresult") ;0=D2D1_FACTORY_TYPE_SINGLE_THREADED, 3=D2D1_DEBUG_LEVEL_INFORMATION
Consistently brings up this error.
image.png
image.png (62.44 KiB) Viewed 458 times
A quick hresult search does not find anything.

Casting to ID2D1DeviceContext5 also does not fix the error hmm...
iPhilip
Posts: 823
Joined: 02 Oct 2013, 12:21

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

11 Apr 2024, 19:53

@iseahound The reason for the error lies in the return type.

Code: Select all

ComCall(48,ID2D1RenderTarget)
assumes that the return type is HRESULT. The documentation page for that method states otherwise:

Code: Select all

void BeginDraw();
Thus, one way to write that line is to use Int as the return type, i.e.

Code: Select all

ComCall(48,ID2D1RenderTarget,'Int')
I struggled with the same issue and, because of that, I have started explicitly adding the return type at the end of all my ComCall's.

I hope this helps.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
MrDoge
Posts: 161
Joined: 27 Apr 2020, 21:29

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

11 Apr 2024, 21:47

@iPhilip thank you so much, I was gonna try WinDbg or something..

my C version doesn't help either..
((HRESULT(*)(void *))(pID2D1RenderTarget[0][48]))(pID2D1RenderTarget); //ID2D1RenderTarget::BeginDraw
and the headers are only in C++, I should have at least manually written C structs

I'll edit my versions, and I hope this is the correct fix

___

also, it seems like 3=D2D1_DEBUG_LEVEL_INFORMATION is optional, so I'll remove it
iseahound
Posts: 1451
Joined: 13 Aug 2016, 21:04
Contact:

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

12 Apr 2024, 07:05

Thanks! I think the strange part is that the return value seemed to always be constant which is weird for a void return value.
iPhilip
Posts: 823
Joined: 02 Oct 2013, 12:21

Re: svgToHBITMAP.ah2 (AddPicture an SVG to Gui)

12 Apr 2024, 10:07

You are welcome.

The key is not to rely on the return value from functions with a void return type. From ComCall's documentation page:
https://www.autohotkey.com/docs/v2/lib/ComCall.htm wrote:If the method is of a type that does not return a value (the void return type in C), specify "Int" or any other numeric type without any suffix (except HRESULT), and ignore the return value. As the content of the return value register is arbitrary in such cases, an exception may or may not be thrown if ReturnType is omitted.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: Bing [Bot], songdg and 24 guests