我们日常操作电脑的时候,经常用代码来操作图片的同学都想要把截图直接保存到图片,并且保存到我想要的位置。
比如我们写sikuli代码的时候药用到大量的图片,我们不可能一一手动去保存,这样效率太低了,通过下面的操作我们可以轻松的用ctrl+v的方式把图片保存到你选中的句柄(文件夹)
通过截图工具snipast截图,然后设置截图输出到指定文件夹,我这是用户目录的pictures目录下。
然后autohotkey脚本监听ctrl+v操作,
如果当前粘贴板中是图片类型:就直接把目标文件夹下(pictures目录)最新的图片复制到当前的句柄(窗口),如果当前句柄(窗口)不是文件夹也不会复制,或者当前粘贴板不是图片类型也不会复制,
如果当前粘贴板中不是图片类型:就直接执行ctrl+v本来操作(就是通过autohotkey再发送一次ctrl+v)
还有一个改变指针状态的小代码,用户判断当前操作是否成功,如果操作成功,指针会出现忙等待的形状,如果没有忙等待说明没有执行复制操作。
为什么用snipast作为截图工具呢?
自动保存图片到指定文件夹,估计也可以通过ahk代码实现(我不会啦~~),但是snipast功能更强大,保存图片的时候可以选择图片质量,在sikuli运用中图片质量很重要的。
;-------------------------------粘贴板图片到文件夹--------------------------------
global CLIPBOARD_ISPIC:=false
CTRLVFLAG:=True
#IF CTRLVFLAG
^v::
desDir:=Explorer_GetPath() "\"
StringReplace, desDir , desDir, `%20, %A_SPACE%, All
;msgBox % desDir
;msgBox % CLIPBOARD_ISPIC
if(InStr(desDir, "Error") or !CLIPBOARD_ISPIC)
{
Send ^v
return
}
;改变鼠标形态
SetSystemCursor()
picDir:=userprofile "\Pictures"
;获取新图片的路径
newPicName:=picDir "\" getPngPath(picDir)
;msgBox %newPicName%
FileCopy ,%newPicName%,%desDir%
;恢复鼠标状态
sleep,500
RestoreCursors()
return
Explorer_GetPath(hwnd="")
{
If !(window := Explorer_GetWindow(hwnd))
Return "Error"
If (window="desktop")
Return A_Desktop
path := window.LocationURL
path := RegExReplace(path, "ftp://.*@","ftp://")
StringReplace, path, path, file:///
StringReplace, path, path, /, `\, All
;Return path
; thanks to polyethene
Loop
If RegExMatch(path, "i)(?<=%)[da-f]{1,2}", hex)
StringReplace, path, path, `%%hex%, % Chr("0x" . hex), All
Else Break
Return path
}
Explorer_GetAll(hwnd="")
{
Return Explorer_Get(hwnd)
}
Explorer_GetSelected(hwnd="")
{
Return Explorer_Get(hwnd,true)
}
Explorer_GetWindow(hwnd="")
{
; thanks to jethrow for some pointers here
WinGet, Process, ProcessName, % "ahk_id" hwnd := hwnd? hwnd:WinExist("A")
WinGetClass class, ahk_id %hwnd%
If (Process!="explorer.exe")
Return
If (class ~= "(Cabinet|Explore)WClass")
{
for window in ComObjCreate("Shell.Application").Windows
If (window.hwnd==hwnd)
Return window
}
Else If (class ~= "Progman|WorkerW")
Return "desktop" ; desktop found
}
Explorer_Get(hwnd="",selection=false)
{
If !(window := Explorer_GetWindow(hwnd))
Return ErrorLevel := "Error"
If (window="desktop")
{
ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
If !hwWindow ; #D mode
ControlGet, hwWindow, HWND,, SysListView321, A
ControlGet, files, List, % ( selection ? "Selected":"") "Col1",,ahk_id %hwWindow%
base := SubStr(A_Desktop,0,1)=="" ? SubStr(A_Desktop,1,-1) : A_Desktop
Loop, Parse, files, `n, `r
{
path := base "" A_LoopField
IfExist %path% ; Ignore special icons like Computer (at least for now)
ret .= path "`n"
}
}
Else
{
If selection
collection := window.document.SelectedItems
Else
collection := window.document.Folder.Items
for item in collection
ret .= item.path "`n"
}
Return Trim(ret,"`n")
}
Return
;改变鼠标指针形态的方法,可以自己设定图片在对应文件夹中看看
SetSystemCursor() ;忙等待
{
IDC_ARROW := 32512
hCursor := DllCall( "LoadCursorFromFile", "Str", "C:\Windows\Cursors\aero_working.ani")
DllCall("SetSystemCursor", "UInt", hCursor, "Int", IDC_ARROW)
}
RestoreCursors() ;正常形态
{
SPI_SETCURSORS := 0x57
DllCall("SystemParametersInfo", "UInt", SPI_SETCURSORS, "UInt", 0, "UInt", 0, "UInt", 0)
}
;返回最新的一张图片
getPngPath(picDir){
uPicPath:="there is no pic in dir picture!"
Loop, %picDir%\*.png
FileList = %FileList%%A_LoopFileTimeModified%`t%A_LoopFileName%`n
Sort, FileList ;根据日期排序.从小到大
Loop, parse, FileList, `n
{
if A_LoopField = ; 忽略列表末尾的最后一个换行符(空项).
continue
StringSplit, FileItem, A_LoopField, %A_Tab% ;用 tab 作为分隔符切割.
;RunWait, %picDir%\%FileItem2%
FileSetAttrib, -R, %picDir%\%FileItem2%
;uPicPath=%picDir%\%FileItem2%
uPicPath=%FileItem2%
}
return uPicPath
}
;检测粘贴板是否变化
OnClipboardChange:
;当包含粘贴板中包含图片的时候才执行ocr操作
if(A_EventInfo!=2)
{
CLIPBOARD_ISPIC:=false
return
}
CLIPBOARD_ISPIC:=True
return
;--------------------------------粘贴板图片到文件夹--------------------------------
源代码下载:
当然我们实际操作的时候只需要运行ahk脚本,然后截图后就可以随心所欲的粘贴图片了。上图只是一个过程。并不是你实际操作的步骤。
这个工具在是在snipast的基础上开发的,截图后保存到指定目录,然后通过截图截取出来,和你选中粘贴板记录没有关系,ahk脚本始终会取出你最新的截图图片。
如果想使用记录,你的选中这个粘贴板记录然后F3(snipast贴图快捷键)粘贴图片到桌面,然后再截图,就可以粘贴了,当然这会降低图片的质量。