Gui support for webp image format Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
MrDoge
Posts: 168
Joined: 27 Apr 2020, 21:29

Re: Gui support for webp image format

24 Apr 2023, 12:12

DataLife wrote:
17 Jul 2019, 17:49
As far as I can determine Windows 10 does not have built-in support for WebP
I want to respond to this

https://stackoverflow.com/questions/43101742/iwicimagingfactorycreatedecoderfromfilename-keeps-the-file-locked-even-after
this was asked in 2017, your post was in 2019, so I think Windows did have built-in support for Webp when you asked your question, unless MSWebp.dll was added later

I found MSWebp.dll in System32 using voidtools Everything (searched webp .dll) the space is intentional
opened MSWebp.dll using IDA, searched "decode", found:
CWICWebpDecoderClassFactory::`scalar deleting destructor'(uint)
then there's msdn documentation for CWICWebpDecoderClassFactory

my first hunch was to take libwebp.dll that google chrome was using, found none,

webpToClipboard_CF_DIB.ah2
viewtopic.php?f=76&t=82050&start=20#p518887

webpToHBITMAP.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.

webpToHBITMAP(webpPath) { ;on second thought, there is no "webp" in this function, maybe it can load any image codec
    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*",&cf:=0)

    IID_IWICImagingFactory:=Buffer(0x10)
    NumPut("UInt64",0x4314C395EC5EC8A9,IID_IWICImagingFactory,0x0)
    NumPut("UInt64",0x70FF35A9D754779C,IID_IWICImagingFactory,0x8)
    ComCall(3,cf,"Ptr",0,"Ptr",IID_IWICImagingFactory,"Ptr*",&pFactory:=0) ;pFactory->CreateInstance

    ComCall(3,pFactory,"Str",webpPath,"Ptr",0,"Uint",0x80000000,"Int",0,"Ptr*",&pDecoder:=0) ;pFactory->CreateDecoderFromFilename

    ComCall(13 ,pDecoder,"Uint",0,"Ptr*",&pFrame:=0) ;pDecoder->GetFrame

    ComCall(10,pFactory,"Ptr*",&pConverter:=0) ;pFactory->CreateFormatConverter

    GUID_WICPixelFormat32bppBGRA:=Buffer(0x10)
    NumPut("UInt64",0x4BFE4E036FDDC324,GUID_WICPixelFormat32bppBGRA,0x0)
    NumPut("UInt64",0x0FC98D76773D85B1,GUID_WICPixelFormat32bppBGRA,0x8)
    ComCall(8,pConverter,"Ptr",pFrame,"Ptr",GUID_WICPixelFormat32bppBGRA,"Int",0,"Ptr",0,"Double",0.0,"Int",0) ;pConverter->Initialize
    ; bpp:=32 ;hard-coded, since above is 32bppBGRA

    ComCall(3,pConverter,"Uint*",&width:=0,"Uint*",&height:=0) ;pConverter->GetSize
    ; cbStride := ((width * bpp + 7) // 8 + 3) & ~3 ; Round up to nearest multiple of 4
    cbStride := width*4 ; I don't understand this, just multiply it by 4

    pData:=Buffer(cbStride * height)

    ComCall(7,pConverter,"Ptr",0,"Uint",cbStride,"Uint",cbStride * height,"Ptr",pData) ;pFlipRotator->CopyPixels

    HBITMAP := DllCall("gdi32\CreateBitmap","Int",width,"Int",height,"Uint",1,"Uint",32,"Ptr",pData,"Ptr")
    return HBITMAP
}
myGui:=Gui()
myGui.AddPicture(,"HBITMAP:" webpToHBITMAP("C:\Users\User\Downloads\img2.webp"))
myGui.Show()

return

f3::Exitapp
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Gui support for webp image format

24 Apr 2023, 13:30

@MrDoge
Nice! :)
I would simplify a bit and add releasing objects:

Code: Select all

#Requires AutoHotkey v2
if !(A_OSVersion ~= "^10")
    throw OSError('this script requires Windows 10 or later')

wnd := Gui()
wnd.MarginX := wnd.MarginY := 0
wnd.AddPicture(, 'HBITMAP: ' . HBitmapFromWebP('test.webp'))
wnd.Show()

HBitmapFromWebP(webpImagePath) {
    static CLSID_WICImagingFactory       := '{CACAF262-9370-4615-A13B-9F5539DA4C0A}'
          , IID_IWICImagingFactory       := '{EC5EC8A9-C395-4314-9C77-54D7A935FF70}'
          , GUID_WICPixelFormat32bppBGRA := '{6FDDC324-4E03-4BFE-B185-3D77768DC90F}'
          , GENERIC_READ := 0x80000000, decodeOption := WICDecodeMetadataCacheOnDemand := 0
          , dither := WICBitmapDitherTypeNone := 0, paletteType := WICBitmapPaletteTypeCustom := 0

    IWICImagingFactory := ComObject(CLSID_WICImagingFactory, IID_IWICImagingFactory)
    ComCall(CreateDecoderFromFilename :=  3, IWICImagingFactory, 'Str', webpImagePath, 'Ptr', 0, 'UInt', GENERIC_READ,
                                                                 'Int', decodeOption, 'PtrP', &pIWICBitmapDecoder := 0)
    ComCall(CreateFormatConverter     := 10, IWICImagingFactory, 'PtrP', &pIWICFormatConverter := 0)

    ComCall(GetFrame := 13, pIWICBitmapDecoder, 'UInt', 0, 'PtrP', &pIWICBitmapFrameDecode := 0)

    DllCall('Ole32\CLSIDFromString', 'Str', GUID_WICPixelFormat32bppBGRA, 'Ptr', CLSID := Buffer(16))
    ComCall(Initialize := 8, pIWICFormatConverter, 'Ptr', pIWICBitmapFrameDecode, 'Ptr', CLSID,
                                                   'Int', dither, 'Ptr', 0, 'Double', 0, 'Int', paletteType)
    ComCall(GetSize    := 3, pIWICFormatConverter, 'UIntP', &width := 0, 'UIntP', &height := 0)

    stride := width * 4
    hBitmap := CreateDIBSection(width, height, &pBits := 0)
    ComCall(CopyPixels := 7, pIWICFormatConverter, 'Ptr', 0, 'UInt', stride, 'UInt', stride * height, 'Ptr', pBits)

    ObjRelease(pIWICFormatConverter), ObjRelease(pIWICBitmapFrameDecode), ObjRelease(pIWICBitmapDecoder)
    return hBitmap
}

CreateDIBSection(w, h, &pBits := 0, bpp := 32) {
    hDC := DllCall('GetDC', 'Ptr', 0, 'Ptr')
    NumPut('UInt', 40, 'UInt', w, 'Int', -h, 'UShort', planes := 1, 'UShort', bpp, BITMAPINFO := Buffer(40, 0))
    hBM := DllCall('CreateDIBSection', 'Ptr', hDC, 'Ptr', BITMAPINFO, 'UInt', 0, 'PtrP', &pBits, 'Ptr', 0, 'UInt', 0, 'Ptr')
    DllCall('ReleaseDC', 'Ptr', 0, 'Ptr', hDC)
    return hBM
}
robodesign
Posts: 936
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: Gui support for webp image format

25 Apr 2023, 11:45

@teadrinker . Can you please provide a version of the HBitmapFromWebP() function for v1 as well ? Thank you .
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Gui support for webp image format

25 Apr 2023, 12:35

For v1:

Code: Select all

Gui, Margin, 0, 0
Gui, Add, Pic,, % "HBITMAP: " . HBitmapFromWebP("test.webp")
Gui, Show

GuiClose() {
   ExitApp
}

HBitmapFromWebP(webpImagePath) {
   static CLSID_WICImagingFactory       := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
         , IID_IWICImagingFactory       := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
         , GUID_WICPixelFormat32bppBGRA := "{6FDDC324-4E03-4BFE-B185-3D77768DC90F}"
         , GENERIC_READ := 0x80000000, decodeOption := WICDecodeMetadataCacheOnDemand := 0
         , dither := WICBitmapDitherTypeNone := 0, paletteType := WICBitmapPaletteTypeCustom := 0
         
   IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
   VTable( IWICImagingFactory, CreateDecoderFromFilename :=  3 ).Call( "Str", webpImagePath, "Ptr", 0, "UInt", GENERIC_READ
                                                                     , "Int", decodeOption, "PtrP", IWICBitmapDecoder )
   VTable( IWICImagingFactory, CreateFormatConverter     := 10 ).Call("PtrP", IWICFormatConverter)
   
   VTable( IWICBitmapDecoder, GetFrame := 13 ).Call("UInt", 0, "PtrP", IWICBitmapFrameDecode)
   
   VarSetCapacity(CLSID, 16)
   DllCall("Ole32\CLSIDFromString", "Str", GUID_WICPixelFormat32bppBGRA, "Ptr", &CLSID)
   VTable( IWICFormatConverter, Initialize := 8 ).Call( "Ptr", IWICBitmapFrameDecode, "Ptr", &CLSID
                                                      , "Int", dither, "Ptr", 0, "Double", 0, "Int", paletteType )
   VTable( IWICFormatConverter, GetSize    := 3 ).Call("UIntP", width, "UIntP", height)
   
   stride := width * 4
   hBitmap := CreateDIBSection(width, height, pBits)
   VTable( IWICFormatConverter, CopyPixels := 7 ).Call("Ptr", 0, "UInt", stride, "UInt", stride * height, "Ptr", pBits)
   
   ObjRelease(IWICFormatConverter), ObjRelease(IWICBitmapFrameDecode)
   ObjRelease(IWICBitmapDecoder), ObjRelease(IWICImagingFactory)
   Return hBitmap
}

Vtable(ptr, n) {
   return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}

CreateDIBSection(w, h, ByRef ppvBits := 0, bpp := 32) {
   hDC := DllCall("GetDC", "Ptr", 0, "Ptr")
   VarSetCapacity(BITMAPINFO, 40, 0)
   NumPut(40 , BITMAPINFO,  0, "UInt")
   NumPut( w , BITMAPINFO,  4, "UInt")
   NumPut(-h , BITMAPINFO,  8, "UInt")
   NumPut( 1 , BITMAPINFO, 12, "UShort")
   NumPut(bpp, BITMAPINFO, 14, "UShort")
   hBM := DllCall("CreateDIBSection", "Ptr", hDC, "Ptr", &BITMAPINFO, "UInt", 0
                                    , "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
   DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
   return hBM
}
robodesign
Posts: 936
Joined: 30 Sep 2017, 03:59
Location: Romania
Contact:

Re: Gui support for webp image format

26 Apr 2023, 11:27

@teadrinker . Thank you very much . It works well. I would give you milk for the tea as a thanks <3.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Gui support for webp image format

26 Apr 2023, 12:04

Not all win10 versions have webp decoder.
Therefore I suggest to check for error in this method CreateDecoderFromFilename and if it returns WINCODEC_ERR_COMPONENTINITIALIZEFAILURE := 0x88982f8B
then need to install webp codec for example from here
https://storage.googleapis.com/downloads.webmproject.org/releases/webp/WebpCodecSetup.exe
Last edited by malcev on 26 Apr 2023, 12:13, edited 1 time in total.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Gui support for webp image format

26 Apr 2023, 12:12

malcev wrote: Therefore I suggest to check for error
You are right, normally in v1 you should check for error every method, but in v2 the exception will be thrown automatically.
william_ahk
Posts: 512
Joined: 03 Dec 2018, 20:02

Re: Gui support for webp image format

13 Jan 2024, 11:26

Gui support for jxl image format when? :D

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], mikeyww, Spawnova and 337 guests