how can i with pressing 1 load a image in to Clipboard and Paste it?

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

Re: how can i with pressing 1 load a image in to Clipboard and Paste it?

Post by MrDoge » 22 Apr 2023, 13:06

I open the clipboard, all I see is CF_DIB, no webp, (used Nirsoft InsideClipboard)
It’s magic that chrome recognizes mimetype webm, and png, I fear that it’s ignoring the CF_DIB and downloading from url

User avatar
mikeyww
Posts: 26947
Joined: 09 Sep 2014, 18:38

Re: how can i with pressing 1 load a image in to Clipboard and Paste it?

Post by mikeyww » 22 Apr 2023, 13:10

If setting the clipboard fails, then there is nothing to paste.

MrDoge
Posts: 160
Joined: 27 Apr 2020, 21:29

Re: how can i with pressing 1 load a image in to Clipboard and Paste it?

Post by MrDoge » 23 Apr 2023, 16:25

in chrome, CF_HDROP takes priority over CF_DIB, if the file doesn't exist, it doesn't fallback to CF_DIB
in Word, CF_HDROP takes priority over CF_DIB, but webp pastes as a file, not an image
firefox copies the image to Temp and puts the path in CF_HDROP, upon change of clipboard, firefox deletes the image in Temp

firefox ^v paste event ignores CF_HDROP completely, looks for CF_DIB, result is png file in javascript api
only firefox drop event(of drag and drop) cares about CF_HDROP I think

the reason why firefox copy paste into Word results in blank image is because "HTML Format" takes priority over CF_HDROP

luckily there is a best possible solution:
"HTML Format" of png
CF_DIB
CF_HDROP of webp

Word will take "HTML Format" (path to png in temp or dataUrl)
Firefox will take the CF_DIB (bitmap)
chrome will take the CF_HDROP (path to webp)

the other solution, which isn't that bad, is to CF_DIB for all 3. only downside is it loses original webp, but only in chrome anyways

I needed and so made a InsideClipboard clone, it doesn't support viewing but it supports deleting, I use both
https://github.com/FuPeiJiang/InsideClipboard.ah2

it's going to be impossible to convert webp into bitmap, so I'm gonna look at your code
"https://s3.amazonaws.com/resizer-dynamic-downloads/webp/0.5.2/x86_64/libwebp.dll"
so no one has support for webp, code it yourself or download a library
if it's inlined into hex or base64 assembly or dll, maybe it could look like it was written in ahk, and not that something really bad needed to happen
but I do use tesseract ocr, an exe, which is probably worse, (not gitignored)

EDIT:

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.

webpToClipboard_CF_DIB(webpPath) {
    ; "Windows has no native support for webp, Says Who?"

    ; DllCall("Ole32\CoInitialize","Ptr",0) ;no need lol
    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(0x28 + cbStride * height)

    NumPut("Uint",0x28,pData,0x0) ;biSize
    NumPut("Int",width,pData,0x4) ;biWidth
    NumPut("Int",height,pData,0x8) ;biHeight
    NumPut("UShort",0x1,pData,0xC) ;biPlanes
    NumPut("UShort",bpp,pData,0xE) ;biBitCount
    NumPut("Uint",0x0,pData,0x10) ;biCompression
    NumPut("Uint",cbStride * height,pData,0x14) ;biSizeImage
    NumPut("UInt64",0x0,pData,0x18) ;biXPelsPerMeter,biYPelsPerMeter
    NumPut("UInt64",0x0,pData,0x20) ;biClrUsed,biClrImportant

    ComCall(13,pFactory,"Ptr*",&pFlipRotator:=0) ;pFactory->CreateBitmapFlipRotator
    ComCall(8,pFlipRotator,"Int",pConverter,"Int",0x10) ;pFlipRotator->Initialize ;0x10=WICBitmapTransformFlipVertical

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

    DllCall("OpenClipboard", "Ptr",DllCall("GetClipboardOwner","Ptr"))
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData","Uint",8,"Ptr",pData) ;8=CF_DIB
    DllCall("CloseClipboard")

}
webpToClipboard_CF_DIB("C:\Users\User\Downloads\img2.webp")

Exitapp

f3::Exitapp
Last edited by MrDoge on 24 Apr 2023, 12:46, edited 1 time in total.

MrDoge
Posts: 160
Joined: 27 Apr 2020, 21:29

Re: how can i with pressing 1 load a image in to Clipboard and Paste it?

Post by MrDoge » 24 Apr 2023, 12:25

I'm gonna rename this function: webpToClipboard_CF_DIB -> imgToClipboard_CF_DIB
(it actually works with any image codec)

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

imgToClipboard_CF_DIB(imgPath) {
    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",imgPath,"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(0x28 + cbStride * height)

    NumPut("Uint",0x28,pData,0x0) ;biSize
    NumPut("Int",width,pData,0x4) ;biWidth
    NumPut("Int",height,pData,0x8) ;biHeight
    NumPut("UShort",0x1,pData,0xC) ;biPlanes
    NumPut("UShort",bpp,pData,0xE) ;biBitCount
    NumPut("Uint",0x0,pData,0x10) ;biCompression
    NumPut("Uint",cbStride * height,pData,0x14) ;biSizeImage
    NumPut("UInt64",0x0,pData,0x18) ;biXPelsPerMeter,biYPelsPerMeter
    NumPut("UInt64",0x0,pData,0x20) ;biClrUsed,biClrImportant

    ComCall(13,pFactory,"Ptr*",&pFlipRotator:=0) ;pFactory->CreateBitmapFlipRotator
    ComCall(8,pFlipRotator,"Int",pConverter,"Int",0x10) ;pFlipRotator->Initialize ;0x10=WICBitmapTransformFlipVertical

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

    DllCall("OpenClipboard", "Ptr",DllCall("GetClipboardOwner","Ptr"))
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData","Uint",8,"Ptr",pData) ;8=CF_DIB
    DllCall("CloseClipboard")

}
imgToClipboard_CF_DIB("C:\Users\User\Downloads\img.webp")
; imgToClipboard_CF_DIB("C:\Users\User\Downloads\img.png") ;works too

Exitapp

f3::Exitapp

qafeh
Posts: 2
Joined: 01 Nov 2022, 20:42

Re: how can i with pressing 1 load a image in to Clipboard and Paste it?

Post by qafeh » 09 Jun 2023, 04:46

mikeyww wrote:
13 Oct 2020, 06:30

Code: Select all

1::
imageFile = D:\0 BALDI VS GRANNY\129 Amoung Us 1\Render\Video\4_A6.png
Clipboard =
FileToClipboard(imageFile)
ClipWait, 2
Sleep, 500
Send ^v
Return

FileToClipboard(PathToCopy, Method := "copy") {
 ; https://autohotkey.com/board/topic/23162-how-to-copy-a-file-to-the-clipboard/page-4
 FileCount := PathLength := 0
 Loop, Parse, PathToCopy, `n, `r ; Count files and total string length
  FileCount++, PathLength+=StrLen(A_LoopField)
 pid := DllCall("GetCurrentProcessId", "uint"), hwnd := WinExist("ahk_pid " . pid)
 ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
 hPath := DllCall("GlobalAlloc", "uint", 0x42, "uint", 20 + (PathLength + FileCount + 1) * 2, "UPtr")
 pPath := DllCall("GlobalLock", "UPtr", hPath)
 NumPut(20, pPath+0), pPath += 16 ; DROPFILES.pFiles = offset of file list
 NumPut(1, pPath+0), pPath += 4 ; fWide = 0 -->ANSI, fWide = 1 -->Unicode
 Offset := 0
 Loop, Parse, PathToCopy, `n, `r ; Rows are delimited by linefeeds (`r`n)
  offset += StrPut(A_LoopField, pPath+offset, StrLen(A_LoopField)+1, "UTF-16") * 2
 DllCall("GlobalUnlock", "UPtr", hPath), DllCall("OpenClipboard", "UPtr", hwnd), DllCall("EmptyClipboard")
 DllCall("SetClipboardData", "uint", 0xF, "UPtr", hPath) ; 0xF = CF_HDROP
 ; Write Preferred DropEffect structure to clipboard to switch between copy/cut operations
 ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
 mem := DllCall("GlobalAlloc", "uint", 0x42, "uint", 4, "UPtr"), str := DllCall("GlobalLock", "UPtr", mem)
 If !(Method ~= "copy|cut") {
  DllCall("CloseClipboard")
  Return
 } Else DllCall("RtlFillMemory", "UPtr", str, "uint", 1, "UChar", (Method = "copy" ? "0x05" : "0x02"))
 DllCall("GlobalUnlock", "UPtr", mem)
 cfFormat := DllCall("RegisterClipboardFormat", "Str", "Preferred DropEffect")
 DllCall("SetClipboardData", "uint", cfFormat, "UPtr", mem)
 DllCall("CloseClipboard")
}
this works perfectly

SKAN wrote:
16 Oct 2020, 04:52
Setting a bitmap to clipboard is simple and shouldn't need any library.

Code: Select all

SetClipboardBitmap( Filename ) {            ; By SKAN on D3AG @ tiny.cc/setclipboardbitmap
Local  HBM := 0,  RES := 0,  OCB := 0,  CF_BITMAP := 2
  If ( HBM := LoadPicture(Filename) )
  If ( HBM := DllCall("CopyImage", "Ptr",HBM, "Int",0, "Int",0, "Int",0, "Int",8, "Ptr") )
  If ( OCB := DllCall("OpenClipboard", "Ptr",A_ScriptHwnd) )
  If DllCall("EmptyClipboard")
     RES := DllCall("SetClipboardData", "Int",CF_BITMAP, "Ptr",HBM)
  OCB := OCB ? DllCall("CloseClipboard")*0 : 0
  HBM := HBM ? DllCall("DeleteObject", "Ptr",HBM)*0 : 0
Return !!RES
}
this one doesnt
it converts jpg to png

Post Reply

Return to “Ask for Help (v1)”