Jump to content

_ScreenCapture_Log() save text directly into image


BigDaddyO
 Share

Recommended Posts

This function would be most useful for individuals that use AutoIt to test applications.

Typically, I have a log file that contains information on what my tests are doing and any failures.  Failures typically get a screenshot and the log gets a link to that screenshot.

I've decided that it would be best to store additional detailed information about the error in the screenshot itself by appending an additional section to the screenshot and adding text into that new section.  It's also able to put a red box around a specific control.  useful if your error is about a specific field value missing or wrong.

Below is a fully operational example script with a couple different capture items that are commented out so you can run 1 at a time.

Please leave any suggestions for improvements.

 

#include <ScreenCapture.au3>
#include <WinAPIConv.au3>

;For this test, ensure the AutoIt spy is open so I can grab a control off that
If WinExists("(Frozen) AutoIt v3 Window Info", "Basic Control Info") = 0 Then
    Run("C:\Program Files (x86)\AutoIt3\Au3Info.exe")
    winwait("(Frozen) AutoIt v3 Window Info", "Basic Control Info", 10)
EndIf

$sSaveAs =  @ScriptDir & "\LogImage.jpg"
$sString = "This is my additional log information that i'm attaching to this screenshot" & @CRLF & @CRLF & "It can handle @CRLF!" & @CRLF & @TAB & "But, it Can't handle @Tab" & @CRLF & @CRLF & _
            "I've highlighted the control we were looking for in a red box!"

$hWindow = WinGetHandle("(Frozen) AutoIt v3 Window Info", "Basic Control Info")
$hCtrl = "Edit3"
$aWinPos = WinGetPos($hWindow, "")


;~ $sOutput = _ScreenCapture_Log($sSaveAs, $sString)    ;Simplest version, capture entire screen, adds 300px wide log to the right

;~ $sOutput = _ScreenCapture_Log($sSaveAs, $sString, $hWindow, $hCtrl, 300, 400)    ;Captures entire screen, highlights a control and adds log to the right

$sOutput = _ScreenCapture_Log($sSaveAs, $sString, $hWindow, $hCtrl, 300, 400, 2, $aWinPos[0], $aWinPos[1], $aWinPos[2], $aWinPos[3])    ;Capture only the window we are looking for, highlight the control, add log to the right
If @error Then
    MsgBox(0, "FAILURE", "Unable to create screenshot")
Else
    ;Launch the saved screenshot to view results
    ShellExecute($sOutput)
EndIf


; #FUNCTION# ====================================================================================================================
; Name...........:  _ScreenCapture_Log
; Description ...:  Captures a screenshot and append a section to include text/log information
; Syntax.........:  _ScreenCapture_Log($sSaveAs, $sString)
; Parameters ....:  $sFileName - Full path where to save the file.  "" to return the GDI image handle
;                   $sString - The full text to append to the image.  Accepts @CRLF but @TAB is not handled
;                   $hWindow - If you want to highlight a control, you must include the handle to the controls window.  Default = "" nothing highlighted
;                   $hCtrl - If you want to highligh a control, add the controlID or handle.  Default = "" nothing highlighted
;                   $iLogW - How wide do you want the appended string image to be.  may be extended automatically depending on position specified.
;                   $iLogH - How high do you want the appended string image to be.  may be extended automatically depending on position specified.
;                   $iLogPos - Where to place the string image.  0 = Left of capture, 1 = Above Capture, 2 = Right of Capture, 3 = Below Capture.  Default = 2 (Right of)
;                   $iCaptX - If you want to capture specific coordinates instead of the entire screen, enter the x coord here
;                   $iCaptY - If you want to capture specific coordinates instead of the entire screen, enter the y coord here
;                   $iCaptW - If you want to capture specific coordinates instead of the entire screen, enter the width here
;                   $iCaptH - If you want to capture specific coordinates instead of the entire screen, enter the height here
;                   $cursor - True = capture the mouse cursor, False = dont capture the cursor.  Default = False
; Return values .: Success - Returns the full path to the saved image, of Handle depending on options provided
;                  Failure - sets @error
; Author ........: BigDaddyO
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: _ScreenCapture_Log(@ScriptDir & "\LogImage.jpg", "This is my Log information")
; ===============================================================================================================================
Func _ScreenCapture_Log($sFileName = "", $sString = "", $hWindow = "", $hCtrl = "", $iLogW = 300, $iLogH = 300, $iLogPos = 2, $iCaptX = 0, $iCaptY = 0, $iCaptW = -1, $iCaptH = -1, $cursor = False)
    Local $hBitmap, $hImage, $aDim[2], $aLogPos[4], $aCaptPos[4], $hCanvas, $hGfx, $aCanvas[2], $aCtrlPos, $tPoint, $aRect[4]
    Local $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo

    _GDIPlus_Startup()

; Capture screen
    If $iCaptW > -1 Then $iCaptW += $iCaptX ;doing this as WinGetPos returns Width instead of x2
    If $iCaptH > -1 Then $iCaptH += $iCaptY ;doing this as WinGetPos returns Height instead of y2
    $hBitmap = _ScreenCapture_Capture("", $iCaptX, $iCaptY, $iCaptW, $iCaptH, $cursor)
    If @error Then
        ConsoleWrite('Failed to perform initial capture using _ScreenCapture_Capture("", ' & $iCaptX & ", " & $iCaptY & ", " & $iCaptW & ", " & $iCaptH & ", " & $cursor & ")" & @CRLF)
        Return SetError(1)
    EndIf
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)


;Build a new Bitmap and Graphic to hold the Screenshot and Log Info
;~  Local $aLogPos[4], $aCaptPos[4], $aCanvas[2]
    $aDim = _GDIPlus_ImageGetDimension($hImage)                     ;Size of our screenshot

    ;Where do we want the log to be located
    Switch $iLogPos
        Case 0  ;Log goes to the left of screenshot
            ;Identify the new size of the image
                If $iLogH > $aDim[1] Then
                    $aCanvas[0] = $aDim[0] + $iLogW
                    $aCanvas[1] = $iLogH
                Else
                    $aCanvas[0] = $aDim[0] + $iLogW
                    $aCanvas[1] = $aDim[1]
                    $iLogH = $aDim[1]
                EndIf
            ;Identify the Size and position of the screenshot in the new image
                $aCaptPos[0] = $iLogW
                $aCaptPos[1] = 0
                $aCaptPos[2] = $aDim[0]
                $aCaptPos[3] = $aDim[1]
            ;Identify the Size and position of the Log text in the new image
                $aLogPos[0] = 5
                $aLogPos[1] = 5
                $aLogPos[2] = $iLogW - 10   ;Width will be specified log width - 10 for a 5px border on both sides
                $aLogPos[3] = $iLogH - 10   ;Log Height - 10 for a 5px border on both sides
            ;Identify the location for the Control Highlight if requested
                If $hWindow <> "" and $hCtrl <> "" Then
                    $aCtrlPos = ControlGetPos($hWindow, "", $hCtrl)             ;Get the location of the control within the window
                    If IsArray($aCtrlPos) Then
                        $tPoint = DllStructCreate("int X;int Y")
                        DllStructSetData($tPoint, "X", $aCtrlPos[0])
                        DllStructSetData($tPoint, "Y", $aCtrlPos[1])
                        _WinAPI_ClientToScreen($hWindow, $tPoint)                   ;Translate the position to the position on screen
                        $aRect[0] = DllStructGetData($tPoint, "X") + $iLogW
                        $aRect[1] = DllStructGetData($tPoint, "Y")
                        $aRect[2] = $aCtrlPos[2]
                        $aRect[3] = $aCtrlPos[3]
                    EndIf
                EndIf

        Case 1  ;Log goes Above the screenshot
            ;Identify the new size of the image
                If $iLogW > $aDim[0] Then
                    $aCanvas[0] = $iLogW
                    $aCanvas[1] = $aDim[1] + $iLogH
                Else
                    $aCanvas[0] = $aDim[0]
                    $aCanvas[1] = $aDim[1] + $iLogH
                    $iLogW = $aDim[0]
                EndIf
            ;Identify the Size and position of the screenshot in the new image
                $aCaptPos[0] = 0
                $aCaptPos[1] = $iLogH
                $aCaptPos[2] = $aDim[0]
                $aCaptPos[3] = $aDim[1]
            ;Identify the Size and position of the Log text in the new image
                $aLogPos[0] = 5
                $aLogPos[1] = 5
                $aLogPos[2] = $aDim[0] - 10
                $aLogPos[3] = $iLogH - 10
            ;Identify the location for the Control Highlight if requested
                If $hWindow <> "" and $hCtrl <> "" Then
                    $aCtrlPos = ControlGetPos($hWindow, "", $hCtrl)             ;Get the location of the control within the window
                    $tPoint = DllStructCreate("int X;int Y")
                    DllStructSetData($tPoint, "X", $aCtrlPos[0])
                    DllStructSetData($tPoint, "Y", $aCtrlPos[1])
                    _WinAPI_ClientToScreen($hWindow, $tPoint)                   ;Translate the position to the position on screen
                    $aRect[0] = DllStructGetData($tPoint, "X")
                    $aRect[1] = DllStructGetData($tPoint, "Y") + $iLogH
                    $aRect[2] = $aCtrlPos[2]
                    $aRect[3] = $aCtrlPos[3]
                EndIf

        Case 2  ;Default, Log goes to the right of the screenshot
            ;Identify the new size of the image
                If $iLogH > $aDim[1] Then
                    $aCanvas[0] = $aDim[0] + $iLogW
                    $aCanvas[1] = $iLogH
                Else
                    $aCanvas[0] = $aDim[0] + $iLogW
                    $aCanvas[1] = $aDim[1]
                    $iLogH = $aDim[1]
                EndIf
            ;Identify the Size and position of the screenshot in the new image
                $aCaptPos[0] = 0
                $aCaptPos[1] = 0
                $aCaptPos[2] = $aDim[0]
                $aCaptPos[3] = $aDim[1]
            ;Identify the Size and position of the Log text in the new image
                $aLogPos[0] = $aDim[0] + 5  ;Start log text after screenshot width + 5 for border
                $aLogPos[1] = 5             ;Start log text at the top of the screenshot with a +5 border
                $aLogPos[2] = $iLogW - 10   ;Width will be specified log width - 10 for a 5px border on both sides
                $aLogPos[3] = $iLogH - 10   ;Width will be specified log height - 10 for a 5px border on both sides
            ;Identify the location for the Control Highlight if requested
                If $hWindow <> "" and $hCtrl <> "" Then
                    $aCtrlPos = ControlGetPos($hWindow, "", $hCtrl)             ;Get the location of the control within the window
                    If IsArray($aCtrlPos) Then
                        $tPoint = DllStructCreate("int X;int Y")
                        DllStructSetData($tPoint, "X", $aCtrlPos[0])
                        DllStructSetData($tPoint, "Y", $aCtrlPos[1])
                        _WinAPI_ClientToScreen($hWindow, $tPoint)                   ;Translate the position to the position on screen
                        $aRect[0] = DllStructGetData($tPoint, "X")
                        $aRect[1] = DllStructGetData($tPoint, "Y")
                        $aRect[2] = $aCtrlPos[2]
                        $aRect[3] = $aCtrlPos[3]
                    EndIf
                EndIf

        Case 3  ;Log goes below the screenshot
            ;Identify the new size of the image
                If $iLogW > $aDim[0] Then
                    $aCanvas[0] = $iLogW
                    $aCanvas[1] = $aDim[1] + $iLogH
                Else
                    $aCanvas[0] = $aDim[0]
                    $aCanvas[1] = $aDim[1] + $iLogH
                    $iLogW = $aDim[0]
                EndIf
            ;Identify the Size and position of the screenshot in the new image
                $aCaptPos[0] = 0
                $aCaptPos[1] = 0
                $aCaptPos[2] = $aDim[0]
                $aCaptPos[3] = $aDim[1]
            ;Identify the Size and position of the Log text in the new image
                $aLogPos[0] = 5
                $aLogPos[1] = $aDim[1] + 5
                $aLogPos[2] = $aDim[0] - 10
                $aLogPos[3] = $iLogH - 10
            ;Identify the location for the Control Highlight if requested
                If $hWindow <> "" and $hCtrl <> "" Then
                    $aCtrlPos = ControlGetPos($hWindow, "", $hCtrl)             ;Get the location of the control within the window
                    If IsArray($aCtrlPos) Then
                        $tPoint = DllStructCreate("int X;int Y")
                        DllStructSetData($tPoint, "X", $aCtrlPos[0])
                        DllStructSetData($tPoint, "Y", $aCtrlPos[1])
                        _WinAPI_ClientToScreen($hWindow, $tPoint)                   ;Translate the position to the position on screen
                        $aRect[0] = DllStructGetData($tPoint, "X")
                        $aRect[1] = DllStructGetData($tPoint, "Y")
                        $aRect[2] = $aCtrlPos[2]
                        $aRect[3] = $aCtrlPos[3]
                    EndIf
                EndIf

        Case Else
            Return SetError(1)
    EndSwitch

    $hCanvas = _GDIPlus_BitmapCreateFromScan0($aCanvas[0], $aCanvas[1])     ;The entire size of the newly widened image
    $hGfx = _GDIPlus_ImageGetGraphicsContext($hCanvas)
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage, $aCaptPos[0], $aCaptPos[1], $aCaptPos[2], $aCaptPos[3])  ;Draw the captured screen in the proper location for the log


;Draw a frame around the control if that option is selected
    If $hWindow <> "" and $hCtrl <> "" Then
        If IsArray($aCtrlPos) Then
            ;If we are not taking a full screen image, then we need to adjust the position of the red rectangle!
            $aRect[0] -= $iCaptX
            $aRect[1] -= $iCaptY
            $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)                                           ;Create a red pen
            _GDIPlus_GraphicsDrawRect($hGfx, $aRect[0], $aRect[1], $aRect[2], $aRect[3], $hPen) ;Draw our rectangle around the control
        EndIf
    EndIf

;Now to insert some text into the canvas
    If $sString <> "" Then
        $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFF99)
        $hFormat = _GDIPlus_StringFormatCreate()
        $hFamily = _GDIPlus_FontFamilyCreate("Arial")
        $hFont = _GDIPlus_FontCreate($hFamily, 8, 2)
        $tLayout = _GDIPlus_RectFCreate($aLogPos[0], $aLogPos[1], $aLogPos[2], $aLogPos[3])
        $aInfo = _GDIPlus_GraphicsMeasureString($hGfx, $sString, $hFont, $tLayout, $hFormat)
        _GDIPlus_GraphicsDrawStringEx($hGfx, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_BrushDispose($hBrush)
    EndIf


    If $sFileName <> "" Then
        ;Save the image
        _GDIPlus_ImageSaveToFile($hCanvas, $sFileName)
        If @error Then
            ConsoleWrite("Failed to save the updated canvas" & @CRLF)
            ;Time for cleanup
            _GDIPlus_ImageDispose($hCanvas)
            _WinAPI_DeleteObject($hImage)
            _GDIPlus_Shutdown()
            Return SetError(1)
        Else
            ConsoleWrite("sucessfully saved the updated canvas" & @CRLF)
            ;Time for cleanup
            _GDIPlus_ImageDispose($hCanvas)
            _WinAPI_DeleteObject($hImage)
            _GDIPlus_Shutdown()
            Return $sFileName
        EndIf
    Else
        ;Return the handle to the canvas, can I shutdown GDIPlus now?
        Return $hCanvas
    EndIf

EndFunc

 

LogImage.jpg

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...