26

Re: AHK: Сохранить скриншот в файл

teadrinker
а есть вариант, чтобы файл автоматически сам выбирался?

27 (изменено: teadrinker, 2018-02-04 20:39:58)

Re: AHK: Сохранить скриншот в файл

Где выбирался?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

28

Re: AHK: Сохранить скриншот в файл

teadrinker
В директории, допустим я укажу где лежит файл C:/User/sobaka.png и он его сам выберет

29

Re: AHK: Сохранить скриншот в файл

Не совсем понял идею, хотите указать папку, и загрузить из неё все файлы изображений? Если не все, а один, то по какому признаку выбирать?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

30 (изменено: Letik, 2018-02-04 21:00:42)

Re: AHK: Сохранить скриншот в файл

teadrinker
ну вот у Вас в коде:

if (!imagePath := A_Args[1])
   FileSelectFile, imagePath,,, Выберите файл изображения для загрузки на imgur.com, Images (*.png; *.bmp; *.tiff; *.tif; *.jpeg; *.jpg; *.gif)

Вот мне нужно, чтоб не выбирать файл в окне, а он сам выбирался автоматически по его местоположению (допустим файл в C:/Pictures/kartinka.png) и он его выбирает сам, без диалоговых окон.

31

Re: AHK: Сохранить скриншот в файл

Пропишите вместо этого нужный файл в переменную imagePath.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

32

Re: AHK: Сохранить скриншот в файл

teadrinker
спасибо большое!

33

Re: AHK: Сохранить скриншот в файл

serzh82saratov пишет:

А вариант со скриншотом можешь заодно запилить, чтобы без файла.

SetBatchLines, -1

ClientID := "7a203d761ce36c4"  ; указать свой ClientID, здесь недействительный
SendScreenshotToImgur(ClientID, [0, 0, 200, 200])
Return

SendScreenshotToImgur(ClientID, oCoords := "", ext := "png", captureCursor := false, jpegQuality := 75)  {
/*
oCoords — массив координат области экрана вида [x, y, w, h], например:
[0, 0, A_ScreenWidth, A_ScreenHeight] или [300, 300, 500, 500]
если массив пустой либо один из элементов пустой или не число — будет сделан скриншот всего виртуального экрана

ext — указать расширение файла, в формате которого будет загружено изображение

captureCursor — если true, курсор будет включён в скриншот

jpegQuality — указать качество, если указано расширение jpeg
*/
   for k, v in ["x", "y", "w", "h"]
      if ( (%v% := oCoords[k]) + 0 = "" && empty := true )
         break
      
   if empty  {
      Sysget, x, 76
      Sysget, y, 77
      Sysget, w, 78
      Sysget, h, 79
   }
   hBitmap := GetHBitmapFromScreen(x, y, w, h, captureCursor)
   gdip := new GDIplus
   pBitmap := gdip.BitmapFromHBitmap(hBitmap)
   DllCall("DeleteObject", Ptr, hBitmap)
   buff := ext
   if ( (size := gdip.SaveBitmap(pBitmap, buff, jpegQuality, true)) < 0 )  {
      Errors := { 1: "Extention " . ext . " doesn't supported. Supported extentions:`nBMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG"
                , 2: "Could not get a list of encoders on system"
                , 3: "Could not find matching encoder for specified file format"
                , 4: "Could not save the bitmap to buffer" }
      MsgBox, 48, Ошибка записи в буфер, % Errors[-size]
      Return
   }
   gdip.DisposeImage(pBitmap)
   
   strBase64 := CryptBinaryToStringBASE64(&buff, size, true)
   http := ComObjCreate("Msxml2.XMLHTTP")
   http.open("POST", "https://api.imgur.com/3/image", true)
   http.onreadystatechange := Func("StateChange").Bind(http)
   http.SetRequestHeader("authorization", "Client-ID " . ClientID)
   http.send(strBase64)
   VarSetCapacity(strBase64, 0), VarSetCapacity(buff, 0)
}

StateChange(http)  {
   if !(http.readyState = 4)
      Return
   
   responsetext := http.responsetext
   if (http.status != 200)  {
      MsgBox, % "Ошибка отправки файла на imgur.com! Status: " . http.status . "`nResponsetext: " . responsetext
      ExitApp
   }
   RegExMatch(responsetext, """link"":""(.*?)""", match)
   link := StrReplace(match1, "\")
   Gui, Imgur: New, +hwndhGui
   Gui, Imgur: Default
   Gui, Font, s9
   Gui, Add, Edit, % "w250 h" . (link ? 24 : 120), % link ? link : responsetext
   Gui, Font
   Gui, Add, Button, x+-80 y+7 w80 h24 gCopyResponse Default, Copy
   GuiControl, Focus, Button1
   Gui, Show,, Imgur.com
   OnMessage( 0x112, Func("WM_SYSCOMMAND").Bind(hGui) )
}

CopyResponse()  {
   GuiControlGet, Clipboard, Imgur:, Edit1
   Gui, Imgur: Destroy
   ExitApp
}

WM_SYSCOMMAND(hGui, wp, lp, msg, hwnd)  {
   static SC_CLOSE := 0xF060
   if (wp = SC_CLOSE && hwnd = hGui)
      ExitApp
}

CryptBinaryToStringBASE64(pData, Bytes, NOCRLF = "")  {
   static CRYPT_STRING_BASE64 := 1, CRYPT_STRING_NOCRLF := 0x40000000
   CRYPT := CRYPT_STRING_BASE64 | (NOCRLF ? CRYPT_STRING_NOCRLF : 0)
   
   DllCall("Crypt32\CryptBinaryToString", Ptr, pData, UInt, Bytes, UInt, CRYPT, Ptr, 0, UIntP, Chars)
   VarSetCapacity(OutData, Chars * (A_IsUnicode ? 2 : 1))
   DllCall("Crypt32\CryptBinaryToString", Ptr, pData, UInt, Bytes, UInt, CRYPT, Str, OutData, UIntP, Chars)
   Return OutData
}

GetHBitmapFromScreen(x, y, w, h, captureCursor)  {
   hDC := DllCall("GetDC", Ptr, 0, Ptr)
   hBM := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, w, Int, h, Ptr)
   hMDC := DllCall("CreateCompatibleDC", Ptr, hDC, Ptr)
   oBM := DllCall("SelectObject", Ptr, hMDC, Ptr, hBM, Ptr)
   DllCall("BitBlt", Ptr, hMDC, Int, 0, Int, 0, Int, w, Int, h, Ptr, hDC, Int, x, Int, y, UInt, 0x00CC0020)
   ( captureCursor && CaptureCursor(hMDC, x, y) )
   DllCall("SelectObject", Ptr, hMDC, Ptr, oBM)
   DllCall("DeleteDC", Ptr, hMDC)
   DllCall("ReleaseDC", Ptr, 0, Ptr, hDC)
   Return hBM  ; should be deleted with DllCall("DeleteObject", Ptr, hBM)
}

CaptureCursor(hDC, x, y)  {
   VarSetCapacity(CURSORINFO, szCI := 4*2 + A_PtrSize + 8, 0)
   NumPut(szCI, CURSORINFO)
   DllCall("GetCursorInfo", Ptr, &CURSORINFO)
   bShow   := NumGet(CURSORINFO, 4, "UInt")
   hCursor := NumGet(CURSORINFO, 4*2)
   xCursor := NumGet(CURSORINFO, 4*2 + A_PtrSize, "Int")
   yCursor := NumGet(CURSORINFO, 4*2 + A_PtrSize + 4, "Int")

   if bShow && hCursor := DllCall("CopyIcon", Ptr, hCursor, Ptr)  {
      VarSetCapacity(ICONINFO, 4*2 + A_PtrSize*3, 0)
      DllCall("GetIconInfo", Ptr, hCursor, Ptr, &ICONINFO)
      bIcon    := NumGet(ICONINFO, "UInt")
      xHotspot := NumGet(ICONINFO, 4, "UInt")
      yHotspot := NumGet(ICONINFO, 4*2, "UInt")
      hBMMask  := NumGet(ICONINFO, 4*2 + A_PtrSize)
      hBMColor := NumGet(ICONINFO, 4*2 + A_PtrSize*2)

      DllCall("DrawIcon", Ptr, hDC, Int, xCursor - xHotspot - x, Int, yCursor - yHotspot - y, Ptr, hCursor)
      DllCall("DestroyIcon", Ptr, hCursor)
      ( hBMMask && DllCall("DeleteObject", Ptr, hBMMask) )
      ( hBMColor && DllCall("DeleteObject", Ptr, hBMColor) )
   }
}

class GDIplus   {
   __New()  {
      if !DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("LoadLibrary", Str, "gdiplus")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", PtrP, pToken, Ptr, &si, Ptr, 0)
      this.token := pToken
   }
   
   __Delete()  {
      DllCall("gdiplus\GdiplusShutdown", Ptr, this.token)
      if hModule := DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("FreeLibrary", Ptr, hModule)
   }
   
   BitmapFromHBitmap(hBitmap, Palette := 0)  {
      DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBitmap, Ptr, Palette, PtrP, pBitmap)
      return pBitmap  ; should be deleted with this.DisposeImage(pBitmap)
   }
   
   SaveBitmap(pBitmap, ByRef info, Quality := 75, tobuff := "")
   {
      ; info — если копируем в буфер, тогда расширение файла, если в файл, тогда путь к файлу
      if tobuff
         Extension := info
      else
         SplitPath, info,,, Extension
      if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
         return -1

      DllCall("gdiplus\GdipGetImageEncodersSize", UintP, nCount, UintP, 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 RegExMatch(Extension, "i)^J(PG|PEG|PE|FIF)$") && Quality != 75  {
         DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, UintP, 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_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
            }
         }      
      }
      if !tobuff
         E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, WStr, info, Ptr, pCodec, UInt, p ? p : 0)
      else  {
         DllCall( "ole32\CreateStreamOnHGlobal", UInt, 0, Int, 1, PtrP, pStream )
         if !E := DllCall( "gdiplus\GdipSaveImageToStream", Ptr, pBitmap, Ptr, pStream, Ptr, pCodec, UInt, p ? p : 0 )  {
            DllCall( "ole32\GetHGlobalFromStream", Ptr, pStream, PtrP, hData )
            pData := DllCall( "GlobalLock", Ptr, hData, Ptr )
            nSize := DllCall( "GlobalSize", Ptr, hData, Ptr )
            VarSetCapacity( info, 0), VarSetCapacity( info, nSize, 0 )
            DllCall( "RtlMoveMemory", Ptr, &info, Ptr, pData, UInt, nSize )
            DllCall( "GlobalUnlock", Ptr, hData )
            DllCall( "GlobalFree", Ptr, hData )
         }
         ObjRelease(pStream)
      }
      return E ? -4 : tobuff ? nSize : 0
   }
   
   DisposeImage(pBitmap)  {
      return DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

34

Re: AHK: Сохранить скриншот в файл

teadrinker, а что, если добавить проверку наличия в буфере изображения, полученного перед запуском скрипта в другой программе? В случае, например, если перед запуском скрипта выделил участок экрана другим скриптом, или нажал Alt+PrnScr и т.д.?

35

Re: AHK: Сохранить скриншот в файл

Это другая задача будет. Здесь мы получаем данные непосредственно с экрана, а если нужно из буфера обмена, есть функция:

Gdip_CreateBitmapFromClipboard()
{
	if !DllCall("OpenClipboard", Ptr, 0)
		return -1
	if !DllCall("IsClipboardFormatAvailable", UInt, 8)
		return -2
	if !hBitmap := DllCall("GetClipboardData", UInt, 2, Ptr)
		return -3
	if !pBitmap := Gdip_CreateBitmapFromHBITMAP(hBitmap)
		return -4
	if !DllCall("CloseClipboard")
		return -5
	DeleteObject(hBitmap)
	return pBitmap
}

Полученный таким образом pBitmap нужно будет вставить вместо

...
   for k, v in ["x", "y", "w", "h"]
      if ( (%v% := oCoords[k]) + 0 = "" && empty := true )
         break
      
   if empty  {
      Sysget, x, 76
      Sysget, y, 77
      Sysget, w, 78
      Sysget, h, 79
   }
   hBitmap := GetHBitmapFromScreen(x, y, w, h, captureCursor)
   gdip := new GDIplus
   pBitmap := gdip.BitmapFromHBitmap(hBitmap)
...
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg
+ DD