AutoHotkey实现粘贴截图到文件夹

背景

 我们日常操作电脑的时候,经常用代码来操作图片的同学都想要把截图直接保存到图片,并且保存到我想要的位置。

 比如我们写sikuli代码的时候药用到大量的图片,我们不可能一一手动去保存,这样效率太低了,通过下面的操作我们可以轻松的用ctrl+v的方式把图片保存到你选中的句柄(文件夹)

 

准备工作

  1. 截图工具 snipast  下载地址:https://www.snipaste.com/
  2. autohotkey v1.0   下载地址:https://www.autohotkey.com/
  3. windows系统        下载地址:https://www.microsoft.com/zh-cn/software-download/windows10

    AutoHotkey实现粘贴截图到文件夹_第1张图片

原理:

 通过截图工具snipast截图,然后设置截图输出到指定文件夹,我这是用户目录的pictures目录下。

AutoHotkey实现粘贴截图到文件夹_第2张图片

然后autohotkey脚本监听ctrl+v操作,

如果当前粘贴板中是图片类型:就直接把目标文件夹下(pictures目录)最新的图片复制到当前的句柄(窗口),如果当前句柄(窗口)不是文件夹也不会复制,或者当前粘贴板不是图片类型也不会复制,

如果当前粘贴板中不是图片类型:就直接执行ctrl+v本来操作(就是通过autohotkey再发送一次ctrl+v)

还有一个改变指针状态的小代码,用户判断当前操作是否成功,如果操作成功,指针会出现忙等待的形状,如果没有忙等待说明没有执行复制操作。

为什么用snipast作为截图工具呢?

自动保存图片到指定文件夹,估计也可以通过ahk代码实现(我不会啦~~),但是snipast功能更强大,保存图片的时候可以选择图片质量,在sikuli运用中图片质量很重要的。

AutoHotkey代码

;-------------------------------粘贴板图片到文件夹--------------------------------
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 
;--------------------------------粘贴板图片到文件夹--------------------------------



源代码下载:

效果展示

AutoHotkey实现粘贴截图到文件夹_第3张图片

当然我们实际操作的时候只需要运行ahk脚本,然后截图后就可以随心所欲的粘贴图片了。上图只是一个过程。并不是你实际操作的步骤。

注意:

这个工具在是在snipast的基础上开发的,截图后保存到指定目录,然后通过截图截取出来,和你选中粘贴板记录没有关系,ahk脚本始终会取出你最新的截图图片。

如果想使用记录,你的选中这个粘贴板记录然后F3(snipast贴图快捷键)粘贴图片到桌面,然后再截图,就可以粘贴了,当然这会降低图片的质量。

你可能感兴趣的:(实用工具,autohotkey,snipast,windows,10)