- Версия MoonLoader
Уважаемые жители БХ, помогите перевести с АХК в Lua. Эта функция много кому пригодится, так как делать скриншоты определенной части экрана + быстрое сохранение без стандартных лагов САМПа при нажатии на F8 + отсутствие проблем с сохранением скрина в случае подмены GPCI хэша. Короче, ребята, кто переведёт, тому огромный респект + закиньте в сниппеты, думаю, лайков соберёте :)
AutoHotKey:
SaveScreenshotToFile(x, y, w, h, filePath) {
hBitmap := GetHBitmapFromScreen(x, y, w, h)
gdip := new GDIplus
pBitmap := gdip.BitmapFromHBitmap(hBitmap)
DllCall("DeleteObject", Ptr, hBitmap)
gdip.SaveBitmapToFile(pBitmap, filePath)
gdip.DisposeImage(pBitmap)
}
GetHBitmapFromScreen(x, y, w, h) {
hDC := DllCall("GetDC", Ptr, 0, Ptr)
hBM := DllCall("CreateCompatibleBitmap", Ptr, hDC, Int, w, Int, h, Ptr)
pDC := DllCall("CreateCompatibleDC", Ptr, hDC, Ptr)
oBM := DllCall("SelectObject", Ptr, pDC, Ptr, hBM, Ptr)
DllCall("BitBlt", Ptr, pDC, Int, 0, Int, 0, Int, w, Int, h, Ptr, hDC, Int, x, Int, y, UInt, 0x00CC0020)
DllCall("SelectObject", Ptr, pDC, Ptr, oBM)
DllCall("DeleteDC", Ptr, pDC)
DllCall("ReleaseDC", Ptr, 0, Ptr, hDC)
Return hBM ; should be deleted with DllCall("DeleteObject", Ptr, hBM)
}
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)
}
SaveBitmapToFile(pBitmap, sOutput, Quality=75) {
SplitPath, sOutput,,, 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 A_IsUnicode
pOutput := &sOutput
else {
VarSetCapacity(wOutput, StrPut(sOutput, "UTF-16")*2, 0)
StrPut(sOutput, &wOutput, "UTF-16")
pOutput := &wOutput
}
E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, pOutput, Ptr, pCodec, UInt, p ? p : 0)
return E ? -5 : 0
}
DisposeImage(pBitmap) {
return DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
}
}