binary data from clipbooard

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
trust_me
Posts: 98
Joined: 29 Jul 2017, 10:46

binary data from clipbooard

07 Nov 2019, 03:47

Part of the code to upload to imgur gets its image data from a file , is there a way to get it directly for an image that is in the clipboard ?

Code: Select all

http:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
img:=ComObjCreate("WIA.ImageFile"),img.LoadFile(image_file)
data:=img.filedata.binarydata

http.Open("POST","https://api.imgur.com/3/upload")
http.SetRequestHeader("Authorization","Client-ID " client)
http.SetRequestHeader("Content-Length",size)
http.Send(data),z:=http.ResponseText

RegExMatch(z, """link"":""\K[^""]+", result)
info["link"]:=StrReplace(result, "\")
RegExMatch(z, """error"":""\K[^""]+", errMsg)
info["error"]:=errMsg
RegExMatch(z, """deletehash"":""\K[^""]+", hash)
info["deletehash"]:=hash
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: binary data from clipbooard

08 Nov 2019, 01:59

Code: Select all

#Include <Gdip_All>
MsgBox, % link := Imgur_UploadFromClipboard("Your_Client_ID")
Run, % link

Imgur_UploadFromClipboard(ClientID) {
	body := ClipImageToByteArray()

	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	; whr.SetProxy(2, "localhost:1080")
	whr.Open("POST", "https://api.imgur.com/3/image", true)
	whr.SetRequestHeader("Authorization", "Client-ID " . ClientID)
	whr.Send(body)
	whr.WaitForResponse()

	if RegExMatch(whr.ResponseText, """link"":""\K[^""]+", result) {
		return StrReplace(result, "\")
	} else {
		RegExMatch(whr.ResponseText, """error"":""\K[^""]+", errMsg)
		throw errMsg ? errMsg : "Unkown Error"
	}
}

ClipImageToByteArray(ext := "png", Quality := 75) {
	pToken := Gdip_Startup()
	pBitmap := Gdip_CreateBitmapFromClipboard()
	if (pBitmap < 0) {
		Gdip_Shutdown(pToken)
		throw "Gdip_CreateBitmapFromClipboard fail: " pBitmap
	}
	byteArr := Gdip_EncodeBitmapToByteArray(pBitmap, ext, Quality)
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown(pToken)
	return byteArr
}

; Modified from iseahound's Gdip_EncodeBitmapToBase64
; https://www.autohotkey.com/boards/viewtopic.php?t=59113&p=248990
Gdip_EncodeBitmapToByteArray(pBitmap, ext, Quality=75) {
	; Thanks to noname.
	if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
		return -1
	Extension := "." Ext

	DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
	VarSetCapacity(ci, nSize)
	DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
	if !(nCount && nSize)
		return -2

	Loop, %nCount%
	{
		sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
		if !InStr(sString, "*" Extension)
			continue

		pCodec := &ci+idx
		break
	}

	if !pCodec
		return -3

	if (Quality != 75)
	{
		Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
		if Extension in .JPG,.JPEG,.JPE,.JFIF
		{
			DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
			VarSetCapacity(EncoderParameters, nSize, 0)
			DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
			Loop, % NumGet(EncoderParameters, "UInt")
			{
				elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
				if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
				{
					p := elem+&EncoderParameters-pad-4
					NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
					break
				}
			}
		}
	}

	DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
	DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint",p ? p : 0)

	DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
	pData := DllCall("GlobalLock", "ptr",hData, "uptr")
	nSize := DllCall("GlobalSize", "uint",pData)

	safeArray := ComObjArray(0x11, nSize) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
	pvData := NumGet(ComObjValue(safeArray) + 12 + (A_PtrSize==8 ? 4 : 0)) ; get pvData memeber
	DllCall("RtlMoveMemory", "ptr", pvData, "ptr", pData, "ptr", nSize)

	DllCall("GlobalUnlock", "ptr",hData)
	DllCall(NumGet(NumGet(pStream + 0, 0, "uptr") + (A_PtrSize * 2), 0, "uptr"), "ptr",pStream)
	DllCall("GlobalFree", "ptr",hData)

	return safeArray
}
:beer:
trust_me
Posts: 98
Joined: 29 Jul 2017, 10:46

Re: binary data from clipbooard

08 Nov 2019, 06:08

Works perfect ! Thank you very much, tmplinshi :D
Did not think it would involve so much coding :shock:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 339 guests