求一个上传图片到谷歌图片搜索的脚本 Topic is solved

遇到了问题?请先进行搜索(中文和英文),然后在此提问

Moderators: tmplinshi, arcticir

sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 18 Oct 2020, 02:32

想把本地的图片上传到谷歌进行搜索,然后在浏览器里查看搜索结果。
论坛里找不到可用的,所以,希望有人可以给我一个可用的范本,或者给我一些提示也行,先感谢!
fwejifjjwk2
Posts: 89
Joined: 10 Aug 2019, 01:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by fwejifjjwk2 » 18 Oct 2020, 07:54

editing
Last edited by fwejifjjwk2 on 05 Apr 2021, 20:16, edited 1 time in total.
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 18 Oct 2020, 09:02

@fwejifjjwk2
谢谢你的回复,但这不是我想要的,我需要纯ahk的实现方法,以便于整合到现有的脚本里去。
论坛里有一个类似的脚本,但是不够能力修改它:
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=80645
fwejifjjwk2
Posts: 89
Joined: 10 Aug 2019, 01:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by fwejifjjwk2 » 19 Oct 2020, 03:55

editing
Last edited by fwejifjjwk2 on 05 Apr 2021, 20:17, edited 1 time in total.
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 19 Oct 2020, 04:46

@fwejifjjwk2
谢谢,请问你说的“ 2. 用連結直接搜索 google image ”,是指手动把图片链接粘贴到谷歌图片搜索栏吗? 如果不是,请提供一下谷歌图片搜索的URL.

版主@arcticir有个帖子分享了 “ 下载图片并上传到 google 搜索 ” 的功能:
https://www.autohotkey.com/boards/viewtopic.php?f=28&t=21821
但提示出错,无法正常执行
fwejifjjwk2
Posts: 89
Joined: 10 Aug 2019, 01:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by fwejifjjwk2 » 19 Oct 2020, 06:03

@sanmaodo

複製圖片到剪貼簿,然後 Run 下面這個腳本。

Code: Select all

#Include UploadToImgur.ahk
; from
; https://www.autohotkey.com/boards/viewtopic.php?t=15697
try {
	result := UploadToImgur(clipboard)
	;MsgBox, 64, Upload Successful!, % result
	Run, "https://www.google.com/searchbyimage?&image_url=%result%"
} catch errMsg {
	MsgBox, 48, Error, % errMsg
}
UploadToImgur.ahk

Code: Select all

; from
; https://www.autohotkey.com/boards/viewtopic.php?t=15697

; Image can be a filename, url or base64
UploadToImgur(Image, ClientID := "fbf77ff49c42c8a", Proxy := "")
{
	if (Image ~= "i)^\s*(ftp|https?)://.+")      ; url
	|| (Image ~= "^\s*[a-zA-Z0-9+/]+={0,2}\s*$") ; base64
		PostData := Image
	else if FileExist(Image)                     ; filename
	{
		file := FileOpen(Image, "r")
		PostData := ComObjArray(0x11, file.length) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
		file.RawRead(NumGet(ComObjValue(PostData) + 8 + A_PtrSize), file.length) ; read raw data
		file.Close()
	}
	else
		throw "Invalid filename/base64/url"

	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Proxy ? whr.SetProxy(2, Proxy) : ""
	whr.Open("POST", "https://api.imgur.com/3/image", true)
	whr.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
	whr.SetRequestHeader("Authorization", "Client-ID " ClientID)
	whr.Send(PostData)
	whr.WaitForResponse()

	if !RegExMatch(whr.ResponseText, """link"":""\K[^""]+", result) {
		RegExMatch(whr.ResponseText, """(message|error)"":""\K[^""]+", err)
		throw, err ? err : whr.ResponseText
	}
	return StrReplace(result, "\")
}
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 19 Oct 2020, 07:17

@fwejifjjwk2
非常感谢!运行脚本十几秒之后,弹出一个空的错误消息框,我猜可能是上传图片的环节出了问题,用你提供的URL直接搜索图片链接,可以正常执行。
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 求一个上传图片到谷歌图片搜索的脚本  Topic is solved

Post by tmplinshi » 22 Oct 2020, 00:39

如果你电脑上有装 ss, 那么使用 UploadToImgur(filename,, "localhost:1080")

上传图片到谷歌图片搜索:

Code: Select all

resultUrl := GoogleSearchByImage_Upload("C:\test.png", "localhost:1080")
Run, % resultUrl

GoogleSearchByImage_Upload(FileName, Proxy := "")
{
	if !FileExist(FileName)
		throw "file not exist"

	CreateFormData( postData, contentType, {encoded_image: [FileName]} )

	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	Proxy ? whr.SetProxy(2, Proxy) : ""
	whr.Open("POST", "https://www.google.com/searchbyimage/upload", true)
	whr.Option(6) := false ; 6 = WinHttpRequestOption_EnableRedirects
	whr.SetRequestHeader("Content-Type", contentType)
	whr.Send(postData)
	whr.WaitForResponse()

	if (whr.Status = 302)
		return whr.GetResponseHeader("Location")
	else
		throw "upload failed"
}

GoogleSearchByImage_Url(ImageUrl)
{
	return "https://www.google.com/searchbyimage?image_url=" . ImageUrl
}

; ===================================================================================
; CreateFormData() by tmplinshi, AHK Topic: https://autohotkey.com/boards/viewtopic.php?t=7647
; Thanks to Coco: https://autohotkey.com/boards/viewtopic.php?p=41731#p41731
; Modified version by SKAN, 09/May/2016
CreateFormData(ByRef retData, ByRef retHeader, objParam) {
	New CreateFormData(retData, retHeader, objParam)
}

Class CreateFormData {

	__New(ByRef retData, ByRef retHeader, objParam) {

		Local CRLF := "`r`n", i, k, v, str, pvData
		; Create a random Boundary
		Local Boundary := this.RandomBoundary()
		Local BoundaryLine := "------------------------------" . Boundary

		this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
		this.Ptr := DllCall( "GlobalAlloc", "UInt",0x40, "UInt",1, "Ptr"  )          ; allocate global memory

		; Loop input paramters
		For k, v in objParam
		{
			If IsObject(v) {
				For i, FileName in v
				{
					str := BoundaryLine . CRLF
					     . "Content-Disposition: form-data; name=""" . k . """; filename=""" . FileName . """" . CRLF
					     . "Content-Type: " . this.MimeType(FileName) . CRLF . CRLF
					this.StrPutUTF8( str )
					this.LoadFromFile( Filename )
					this.StrPutUTF8( CRLF )
				}
			} Else {
				str := BoundaryLine . CRLF
				     . "Content-Disposition: form-data; name=""" . k """" . CRLF . CRLF
				     . v . CRLF
				this.StrPutUTF8( str )
			}
		}

		this.StrPutUTF8( BoundaryLine . "--" . CRLF )

		; Create a bytearray and copy data in to it.
		retData := ComObjArray( 0x11, this.Len ) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
		pvData  := NumGet( ComObjValue( retData ) + 8 + A_PtrSize )
		DllCall( "RtlMoveMemory", "Ptr",pvData, "Ptr",this.Ptr, "Ptr",this.Len )

		this.Ptr := DllCall( "GlobalFree", "Ptr",this.Ptr, "Ptr" )                   ; free global memory 

		retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
	}

	StrPutUTF8( str ) {
		Local ReqSz := StrPut( str, "utf-8" ) - 1
		this.Len += ReqSz                                  ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42
		this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len + 1, "UInt", 0x42 )   
		StrPut( str, this.Ptr + this.len - ReqSz, ReqSz, "utf-8" )
	}
  
	LoadFromFile( Filename ) {
		Local objFile := FileOpen( FileName, "r" )
		this.Len += objFile.Length                     ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42 
		this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len, "UInt", 0x42 )
		objFile.RawRead( this.Ptr + this.Len - objFile.length, objFile.length )
		objFile.Close()       
	}

	RandomBoundary() {
		str := "0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
		Sort, str, D| Random
		str := StrReplace(str, "|")
		Return SubStr(str, 1, 12)
	}

	MimeType(FileName) {
		n := FileOpen(FileName, "r").ReadUInt()
		Return (n        = 0x474E5089) ? "image/png"
		     : (n        = 0x38464947) ? "image/gif"
		     : (n&0xFFFF = 0x4D42    ) ? "image/bmp"
		     : (n&0xFFFF = 0xD8FF    ) ? "image/jpeg"
		     : (n&0xFFFF = 0x4949    ) ? "image/tiff"
		     : (n&0xFFFF = 0x4D4D    ) ? "image/tiff"
		     : "application/octet-stream"
	}

}
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 22 Oct 2020, 07:32

@tmplinshi
完美的实现了,这正是我想要的,非常感谢!!! :dance: :salute:
fwejifjjwk2
Posts: 89
Joined: 10 Aug 2019, 01:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by fwejifjjwk2 » 22 Oct 2020, 08:10

@tmplinshi
這段代碼在我的電腦上運行起來有錯誤
在第9行的 CreateFormDate

Code: Select all

Error: 0x80072EFD-
Source: WinHttp.WinHttpRequest
Description: 無法建立與伺服器的連線
HelpFile: (null)
HelpContext: 0
Specifically: WaitForResponse
我註釋掉這行就可以正常搜索了

Code: Select all

Proxy ? whr.SetProxy(2, Proxy) : ""
另外什麼是 ss?
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 22 Oct 2020, 09:15

@fwejifjjwk2 ss 就是 Shadowsocks
pk23
Posts: 110
Joined: 24 Apr 2015, 00:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by pk23 » 23 Oct 2020, 22:33

@tmplinshi 咦,原来CreateFormData的作者竟然是同胞啊,那能不能提一个特性请求,让CreateFormData支持PUT方法?(起因是这个帖子需要用)
原先我想自己改……但发现__New() 里面写死了各个paramters的组装,不太好拆出来,最后只好单独把BinArr_FromFile和MimeType俩函数拷贝出来用了(虽然也不是不行,但要原生支持就更好了
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by tmplinshi » 24 Oct 2020, 11:11

@pk23
CreateFormData 是用来创建 Content-Type 为 multipart/form-data 的数据, 与你使用什么请求方法并没有关系.

multipart/form-data 类型的数据是由键值组成的, 而你那个帖子提到的 API 显然不是接收这种类型的数据, 它仅仅需要文件数据本身, 没有什么键名. 你不需要设置 Content-Type, 只需要使用 whr.Send( BinArr_FromFile(filepath) ), 或者使用 malcev 的方法:

Code: Select all

...
whr.Send( fileToSafeArray(filePath) )

fileToSafeArray(filePath) {
	f := FileOpen(filePath, "r")
	safeArray := ComObjArray(VT_UI1 := 0x11, f.length)
	pvData := NumGet(ComObjValue(safeArray) + 8 + A_PtrSize)
	f.RawRead(pvData + 0, f.length)
	f.Close()
	return safeArray
}
pk23
Posts: 110
Joined: 24 Apr 2015, 00:49

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by pk23 » 24 Oct 2020, 18:08

@tmplinshi 谢谢! malcev这个写法其实我看不太懂,但是也没关系,封装起来能调用就行了!多谢改成函数:)
sanmaodo
Posts: 45
Joined: 28 Aug 2020, 01:39

Re: 求一个上传图片到谷歌图片搜索的脚本

Post by sanmaodo » 26 Mar 2021, 02:31

@tmplinshi 您好!
在脚本的使用过程中,我碰到了一些特别的情况,有时需要上传的对象并没有被保存为图档,它只是一个 Gdip 生成的 pBitmap,或者它是一串 base64 数据。
请问,能否将其直接上传?可以话,希望能告诉我具体方法。

感谢先! :D
Post Reply

Return to “请求帮助”