Captura de Pantalla

Esta sección es para preguntas sobre programación/scripting usando AutoHotkey.

Moderator: Flipeador

YangCarlo
Posts: 1
Joined: 16 Aug 2019, 17:56

Captura de Pantalla

16 Aug 2019, 18:39

Hola, por favor alguien que pueda ayudarme, necesito saber como puedo logran que al aplicar la combinación de teclas "Alt+p" se tome una captura de pantalla y se guarde en un directorio especifico, la verdad soy nuevo y apenas he aprendido a utiliza lo básico, por su ayuda muchas gracias, lo necesito para facilitar unos procedimientos en mi trabajo. ;)
User avatar
Flipeador
Posts: 1146
Joined: 15 Nov 2014, 21:31
GitHub: Flipeador
Location: Argentina
Contact:

Re: Captura de Pantalla

17 Aug 2019, 10:07

En el antiguo foro hay un tema al respecto. El código es medio feo pero funciona.
Guarda la imagen en el escritorio.

Code: Select all

#NoEnv
#SingleInstance Force
SetBatchLines -1


!p::  ; Alt+p
File := A_Desktop . "\" . A_Now . ".bmp"  ; Donde guardar la imagen.
CaptureScreen(,, File)
return




CaptureScreen(aRect := 0, bCursor := False, sFile := "", nQuality := "")
{
    If !aRect
    {
        SysGet, nL, 76  ; virtual screen left & top
        SysGet, nT, 77
        SysGet, nW, 78  ; virtual screen width and height
        SysGet, nH, 79
    }
    Else If aRect = 1
        WinGetPos, nL, nT, nW, nH, A
    Else If aRect = 2
    {
        WinGet, hWnd, ID, A
        VarSetCapacity(rt, 16, 0)
        DllCall("GetClientRect" , "ptr", hWnd, "ptr", &rt)
        DllCall("ClientToScreen", "ptr", hWnd, "ptr", &rt)
        nL := NumGet(rt, 0, "int")
        nT := NumGet(rt, 4, "int")
        nW := NumGet(rt, 8)
        nH := NumGet(rt,12)
    }
    Else If aRect = 3
    {
        VarSetCapacity(mi, 40, 0)
        DllCall("GetCursorPos", "int64P", pt), NumPut(40,mi,0,"uint")
        DllCall("GetMonitorInfo", "ptr", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2, "ptr"), "ptr", &mi)
        nL := NumGet(mi, 4, "int")
        nT := NumGet(mi, 8, "int")
        nW := NumGet(mi,12, "int") - nL
        nH := NumGet(mi,16, "int") - nT
    }
    Else
    {
        StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
        nL := rt1   ; convert the Left,top, right, bottom into left, top, width, height
        nT := rt2
        nW := rt3 - rt1
        nH := rt4 - rt2
        znW := rt5
        znH := rt6
    }

    mDC := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
    hBM := CreateDIBSection(mDC, nW, nH)
    oBM := DllCall("SelectObject", "ptr", mDC, "ptr", hBM, "ptr")
    hDC := DllCall("GetDC", "ptr", 0, "ptr")
    DllCall("BitBlt", "ptr", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "ptr", hDC, "int", nL, "int", nT, "Uint", 0x40CC0020)
    DllCall("ReleaseDC", "ptr", 0, "ptr", hDC)
    If bCursor
        CaptureCursor(mDC, nL, nT)
    DllCall("SelectObject", "ptr", mDC, "ptr", oBM)
    DllCall("DeleteDC", "ptr", mDC)
    If znW && znH
        hBM := Zoomer(hBM, nW, nH, znW, znH)
    If sFile = 0
        SetClipboardData(hBM)
    Else Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "ptr", hBM)
}

CaptureCursor(hDC, nL, nT)
{
    VarSetCapacity(mi, 32, 0), Numput(16+A_PtrSize, mi, 0, "uint")
    DllCall("GetCursorInfo", "ptr", &mi)
    bShow   := NumGet(mi, 4, "uint")
    hCursor := NumGet(mi, 8)
    xCursor := NumGet(mi,8+A_PtrSize, "int")
    yCursor := NumGet(mi,12+A_PtrSize, "int")

    DllCall("GetIconInfo", "ptr", hCursor, "ptr", &mi)
    xHotspot := NumGet(mi, 4, "uint")
    yHotspot := NumGet(mi, 8, "uint")
    hBMMask  := NumGet(mi,8+A_PtrSize)
    hBMColor := NumGet(mi,16+A_PtrSize)

    If bShow
        DllCall("DrawIcon", "ptr", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "ptr", hCursor)
    If hBMMask
        DllCall("DeleteObject", "ptr", hBMMask)
    If hBMColor
        DllCall("DeleteObject", "ptr", hBMColor)
}

Zoomer(hBM, nW, nH, znW, znH)
{
    mDC1 := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
    mDC2 := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
    zhBM := CreateDIBSection(mDC2, znW, znH)
    oBM1 := DllCall("SelectObject", "ptr", mDC1, "ptr",  hBM, "ptr")
    oBM2 := DllCall("SelectObject", "ptr", mDC2, "ptr", zhBM, "ptr")
    DllCall("SetStretchBltMode", "ptr", mDC2, "int", 4)
    DllCall("StretchBlt", "ptr", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "ptr", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
    DllCall("SelectObject", "ptr", mDC1, "ptr", oBM1)
    DllCall("SelectObject", "ptr", mDC2, "ptr", oBM2)
    DllCall("DeleteDC", "ptr", mDC1)
    DllCall("DeleteDC", "ptr", mDC2)
    DllCall("DeleteObject", "ptr", hBM)
    Return zhBM
}

Convert(sFileFr := "", sFileTo := "", nQuality := "")
{
    If (sFileTo = "")
        sFileTo := A_ScriptDir . "\screen.bmp"
    SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo
    
    If Not hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll", "ptr")
        Return  sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo (sDirTo = "" ? "" : "\") sNameTo ".bmp") : ""
    VarSetCapacity(si, 16, 0), si := Chr(1)
    DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "ptr", &si, "ptr", 0)

    If !sFileFr
    {
        DllCall("OpenClipboard", "ptr", 0)
        If  (DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2, "ptr")))
            DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", hBM, "ptr", 0, "ptr*", pImage)
        DllCall("CloseClipboard")
    }
    Else If sFileFr Is Integer
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", sFileFr, "ptr", 0, "ptr*", pImage)
    Else    DllCall("gdiplus\GdipLoadImageFromFile", "wstr", sFileFr, "ptr*", pImage)
    DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
    VarSetCapacity(ci,nSize,0)
    DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "ptr", &ci)
    struct_size := 48+7*A_PtrSize, offset := 32 + 3*A_PtrSize, pCodec := &ci - struct_size
    Loop, % nCount
        If InStr(StrGet(Numget(offset + (pCodec+=struct_size)), "utf-16") , "." . sExtTo)
            break

    If (InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec < &ci + nSize)
    {
        DllCall("gdiplus\GdipGetEncoderParameterListSize", "ptr", pImage, "ptr", pCodec, "UintP", nCount)
        VarSetCapacity(pi,nCount,0), struct_size := 24 + A_PtrSize
        DllCall("gdiplus\GdipGetEncoderParameterList", "ptr", pImage, "ptr", pCodec, "Uint", nCount, "ptr", &pi)
        Loop, % NumGet(pi,0,"uint")
            If (NumGet(pi,struct_size*(A_Index-1)+16+A_PtrSize,"uint")=1 && NumGet(pi,struct_size*(A_Index-1)+20+A_PtrSize,"uint")=6)
            {
                pParam := &pi+struct_size*(A_Index-1)
                NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0,"uint")+16+A_PtrSize,"uint")),"uint")
                Break
            }
    }

    If pImage
        pCodec < &ci + nSize    ? DllCall("gdiplus\GdipSaveImageToFile", "ptr", pImage, "wstr", sFileTo, "ptr", pCodec, "ptr", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pImage, "ptr*", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "ptr", pImage)

    DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
    DllCall("FreeLibrary", "ptr", hGdiPlus)
}


CreateDIBSection(hDC, nW, nH, bpp := 32, ByRef pBits := "")
{
    VarSetCapacity(bi, 40, 0)
    NumPut(40, bi, "uint")
    NumPut(nW, bi, 4, "int")
    NumPut(nH, bi, 8, "int")
    NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
    Return DllCall("gdi32\CreateDIBSection", "ptr", hDC, "ptr", &bi, "Uint", 0, "UintP", pBits, "ptr", 0, "Uint", 0, "ptr")
}

SaveHBITMAPToFile(hBitmap, sFile)
{
    VarSetCapacity(oi,104,0)
    DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
    fObj := FileOpen(sFile, "w")
    fObj.WriteShort(0x4D42)
    fObj.WriteInt(54+NumGet(oi,36+2*A_PtrSize,"uint"))
    fObj.WriteInt64(54<<32)
    fObj.RawWrite(&oi + 16 + 2*A_PtrSize, 40)
    fObj.RawWrite(NumGet(oi, 16+A_PtrSize), NumGet(oi,36+2*A_PtrSize,"uint"))
    fObj.Close()
}

SetClipboardData(hBitmap)
{
    VarSetCapacity(oi,104,0)
    DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
    sz := NumGet(oi,36+2*A_PtrSize,"uint")
    hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uptr", 40+sz, "ptr")
    pDIB := DllCall("GlobalLock", "ptr", hDIB, "ptr")
    DllCall("RtlMoveMemory", "ptr", pDIB, "ptr", &oi + 16 + 2*A_PtrSize, "Uptr", 40)
    DllCall("RtlMoveMemory", "ptr", pDIB+40, "ptr", NumGet(oi, 16+A_PtrSize), "Uptr", sz)
    DllCall("GlobalUnlock", "ptr", hDIB)
    DllCall("DeleteObject", "ptr", hBitmap)
    DllCall("OpenClipboard", "ptr", 0)
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData", "Uint", 8, "ptr", hDIB)
    DllCall("CloseClipboard")
}
https://autohotkey.com/board/topic/121619-screencaptureahk-broken-capturescreen-function-win-81-x64/
garry
Posts: 1885
Joined: 22 Dec 2013, 12:50

Re: Captura de Pantalla

17 Aug 2019, 13:32

gracias, un script con gdip.ahk

Code: Select all

#SingleInstance force
#NoTrayIcon
#Include Gdip.ahk

^!F11::                       ;- ctrl+alt+F11
token := Gdip_Startup()
SysGet, VirtualScreenX, 76
SysGet, VirtualScreenY, 77
SysGet, VirtualScreenWidth, 78
SysGet, VirtualScreenHeight, 79
Image:= Gdip_Bitmapfromscreen(VirtualScreenX "|" VirtualScreenY "|" VirtualScreenWidth "|" VirtualScreenHeight)
where:= a_desktop . "\" . a_now ".PNG"
cr   := Gdip_Savebitmaptofile(Image,where)
Gdip_DisposeImage(Image)
Gdip_Shutdown(token)
return

Return to “Pedir Ayuda”

Who is online

Users browsing this forum: No registered users and 8 guests