Jump to content

Screen Capture from clipboard


semedboy
 Share

Recommended Posts

i was using the build in function

_ScreenCapture_Capture
and it seems that it fails to capture my taskbar.... so i did this UDF

#include-once
#include <gdiplus.au3>
#include <ClipBoard.au3>

; #FUNCTION# ====================================================================================================================
; Name...........: _ScreenCapture
; Description ...: Captures screen from clipboard
; Syntax.........: _ScreenCapture($iFile)
; Parameters ....:
; Return values .: Success      - True
;                  Failure      - False
; Author ........: Semedboy (Abdulselam)
; E-mail ........: semedboy@gmail.com
; Related .......: _GDIPlus_Startup,_GDIPlus_BitmapCreateFromHBITMAP,_ClipBoard_GetData,_GDIPlus_ImageSaveToFile
; Example .......; Yes
; ===============================================================================================================================

Func _ScreenCapture($ifile)
    Local $Clip_image,$save
    If $ifile<>"" Then      
        Send("{PRINTSCREEN}")
        _GDIPlus_Startup()
        $Clip_image=_GDIPlus_BitmapCreateFromHBITMAP(_ClipBoard_GetData ($CF_BITMAP))
        $Save=_GDIPlus_ImageSaveToFile($Clip_image,$ifile)
        Return $save
    Else
        ConsoleWrite("Function syntax == _ScreenCapture($File)"&@CRLF&"==> Error ==> No file specified"&@CRLF)
        Exit
    EndIf
EndFunc   ;==>_ScreenCapture

_ScreenCapture(@ScriptDir&"\_ScreenCapture test.bmp")

comments are appreciated

0x5748415420444F20594F552057414E543F

Link to comment
Share on other sites

Nice idea, but does not work (Windows XP). I rewrote your function.

#Include <ClipBoard.au3>
#Include <GDIPlus.au3>

Func _ScreenCapture($sFile)

    Local $Result, $Timer, $hImage, $hBitmap = 0

    ClipPut('')
    Send('{PRINTSCREEN}')
    $Timer = TimerInit()
    While TimerDiff($Timer) < 1000
        _ClipBoard_Open(0)
        $hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)
        _ClipBoard_Close()
        If $hBitmap Then
            ExitLoop
        EndIf
        Sleep(10)
    WEnd
    If Not $hBitmap Then
        Return 0
    EndIf
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $Result = _GDIPlus_ImageSaveToFile($hImage, $sFile)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    Return $Result
EndFunc   ;==>_ScreenCapture

_ScreenCapture(@ScriptDir & '\Screenshot.bmp')
Edited by Yashied
Link to comment
Share on other sites

I rewrote your function.

Yes, it works. Would you like to extend this clipboard sample on case of

Enhanced Metafile (EMF)? So instead of bitmap image getting:

$hBitmap = _ClipBoard_GetDataEx($CF_BITMAP)

it will be clipboard with EMF content

$hEnMetaFile = _ClipBoard_GetDataEx($CF_ENHMETAFILE)

Is there way to convert this $hEnMetaFile into bitmap image?

Thanx

The point of world view

Link to comment
Share on other sites

Its function is based on Send('{PRINTSCREEN}')

In other case ({Ctrl-C}) clipboard can have other images (not bitmap!).

I don't understand, why EMF?

Sorry! Don't trouble, please.

This image is really very hard for you, I think.

The point of world view

Link to comment
Share on other sites

Link to comment
Share on other sites

And what is the reason for this post?

Now I'm just looking for something to work with EMF.

For example. This one (rewritten from

this example) can view any images (incl. *.emf) and save it as Sample.jpg:

#include <GuiConstantsEx.au3>
#include <ScreenCapture.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global $Caption = "APreview"
Global $FileSaved = @ScriptDir & "\Sample.jpg"
Global $ClassID = "[CLASS:ShImgVw:CZoomWnd; INSTANCE:1]"
Global $hGUI_OBJ

Opt("GUIOnEventMode", True)

$oPreview = ObjCreate("Preview.Preview")

$GUI = GUICreate($Caption, 640, 580)

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

$Button1 = GUICtrlCreateButton("Load", 50, 10, 40, 20)
GUICtrlSetOnEvent(-1, "_LoadPicture")

$Button2 = GUICtrlCreateButton("-", 100, 10, 20, 20)
GUICtrlSetOnEvent(-1, "_Zoom")

$Button3 = GUICtrlCreateButton("+", 130, 10, 20, 20)
GUICtrlSetOnEvent(-1, "_Zoom")

$Button4 = GUICtrlCreateButton("Save", 160, 10, 40, 20)
GUICtrlSetOnEvent(-1, "_Save")

$GUI_OBJ = GUICtrlCreateObj($oPreview, 10, 50, 620, 520)
GUICtrlSetState($GUI_OBJ, $GUI_NOFOCUS)

GUISetState()
$hGUI_OBJ = ControlGetHandle($Caption, "", $ClassID)

While 1
    Sleep(100)
WEnd

;===========================
Func _LoadPicture()
    $sFile = FileOpenDialog("Open Image", @ScriptDir, "Image files (*.bmp;*.jpg;*.jpeg;*.wmf;*.emf)", 1)
    If @error Then Return
    $oPreview.ShowFile ($sFile, 1)
EndFunc   ;==>_LoadPicture

Func _Zoom()
    Switch @GUI_CtrlId
        Case $Button2
            $oPreview.Zoom (-1)
        Case $Button3
            $oPreview.Zoom (1)
    EndSwitch
EndFunc   ;==>_Zoom

;===========================
Func _Save()
local $hBitmap
  $hBitmap = _ScreenCapture_CaptureWnd($FileSaved, $hGUI_OBJ)
  _WinAPI_DeleteObject($hBitmap)
EndFunc   ;==>_Save

;===========================
Func _Exit()
 Exit
EndFunc   ;==>_Exit

Is there other way to convert EMFile into bitmap image?

The point of world view

Link to comment
Share on other sites

Is there other way to convert EMFile into bitmap image?

#Include <GDIPlus.au3>
#Include <WinAPI.au3>

$sFrom = @ScriptDir & '\test.emf'
$sTo = @ScriptDir & '\test.bmp'

_GDIPlus_Startup()
$hEmf = _GDIPlus_ImageLoadFromFile($sFrom)
$W = _GDIPlus_ImageGetWidth($hEmf)
$H = _GDIPlus_ImageGetHeight($hEmf)
$hBitmap = _WinAPI_CreateBitmap($W, $H, 1, 32)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
_GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $W, $H, $hBrush)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hEmf, 0, 0, $W, $H)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hEmf)

ConsoleWrite($hBitmap & @CR)

#cs

; Save to...
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_GDIPlus_ImageSaveToFile($hImage, $sTo)
_GDIPlus_ImageDispose($hImage)

#ce

_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()
Edited by Yashied
Link to comment
Share on other sites

Is a nice idea but original post did not work for me either. :mellow: Im using windows 7. Yashieds post did work though.

Link to comment
Share on other sites

original post did not work for me either

Maybe. I have not here Win7. Has your version of Win7 file

shimgvw.dll registered?

BTW Some note about script with ObjCreate("Preview.Preview"). It also knows about Drag & Drop operation. You can place into it any images from other application ie FireFox, Windows Explore, IE and so on.

The point of world view

Link to comment
Share on other sites

I hate to say but the quality of bitmap obtained is bad (fonts).

Yes, I see. The following example works fine, try.

#Include <GDIPlus.au3>
#Include <WinAPI.au3>

Global Const $tagENHMETAHEADER = 'dword Type;dword Size;long rcBounds[4];long rcFrame[4];dword Signature;dword Version;dword Bytes;dword Records;word Handles;word Reserved;dword Description;dword OffDescription;dword PalEntries;long Device[2];long Millimeters[2];dword PixelFormat;dword OffPixelFormat;dword OpenGL;long Micrometers[2];'

_GDIPlus_Startup()
$hBitmap = _GetHBitmapFromEmf(@ScriptDir & '\Graph.emf')
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_ImageSaveToFile($hImage, @ScriptDir & '\Graph.bmp')
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

Func _GetHBitmapFromEmf($sFile, $iW = -1, $iH = -1, $iRGB = 0xFFFFFF)

    Local $hEmf = _WinAPI_GetEnhMetaFile($sFile)

    If Not $hEmf Then
        Return 0
    EndIf

    Local $hDC, $hMemDC, $hMemSv, $hBitmap, $tHeader, $tRect

    $hDC = _WinAPI_GetDC(0)
    If ($iW < 0) Or ($iH < 0) Then
        $tHeader = _WinAPI_GetEnhMetaFileHeader($hEmf)
        If $iW < 0 Then
            $iW = Round((DllStructGetData($tHeader, 'rcFrame', 3) - DllStructGetData($tHeader, 'rcFrame', 1)) * DllStructGetData($tHeader, 'Device', 1) / DllStructGetData($tHeader, 'Millimeters', 1) / 100)
        EndIf
        If $iH < 0 Then
            $iH = Round((DllStructGetData($tHeader, 'rcFrame', 4) - DllStructGetData($tHeader, 'rcFrame', 2)) * DllStructGetData($tHeader, 'Device', 2) / DllStructGetData($tHeader, 'Millimeters', 2) / 100)
        EndIf
    EndIf
    $tRect = DllStructCreate($tagRECT)
    DllStructSetData($tRect, 1, 0)
    DllStructSetData($tRect, 2, 0)
    DllStructSetData($tRect, 3, $iW)
    DllStructSetData($tRect, 4, $iH)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateSolidBitmap(0, $iRGB, $iW, $iH)
    $hMemSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
    _WinAPI_PlayEnhMetaFile($hMemDC, $hEmf, $tRect)
    _WinAPI_DeleteEnhMetaFile($hEmf)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_SelectObject($hMemDC, $hMemSv)
    _WinAPI_DeleteDC($hMemDC)
    Return $hBitmap
EndFunc   ;==>_GetHBitmapFromEmf

#Region WinAPI Functions

Func _WinAPI_DeleteEnhMetaFile($hEmf)

    Local $Ret = DllCall('gdi32.dll', 'int', 'DeleteEnhMetaFile', 'ptr', $hEmf)

    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return 1
EndFunc   ;==>_WinAPI_DeleteEnhMetaFile

Func _WinAPI_GetEnhMetaFile($sFile)

    Local $Ret = DllCall('gdi32.dll', 'ptr', 'GetEnhMetaFileW', 'wstr', $sFile)

    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[0]
EndFunc   ;==>_WinAPI_GetEnhMetaFile

Func _WinAPI_GetEnhMetaFileHeader($hEmf)

    Local $tENHMETAHEADER = DllStructCreate($tagENHMETAHEADER)
    Local $Ret = DllCall('gdi32.dll', 'uint', 'GetEnhMetaFileHeader', 'ptr', $hEmf, 'uint', DllStructGetSize($tENHMETAHEADER), 'ptr', DllStructGetPtr($tENHMETAHEADER))

    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return SetError(0, $Ret[0], $tENHMETAHEADER)
EndFunc   ;==>_WinAPI_GetEnhMetaFileHeader

Func _WinAPI_PlayEnhMetaFile($hDC, $hEmf, $tRECT)

    Local $Ret = DllCall('gdi32.dll', 'int', 'PlayEnhMetaFile', 'hwnd', $hDC, 'ptr', $hEmf, 'ptr', DllStructGetPtr($tRECT))

    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return 1
EndFunc   ;==>_WinAPI_PlayEnhMetaFile

#EndRegion WinAPI Functions

I will include support for metafiles in the next version of the WinAPIEx UDF library.

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...