Sign in to follow this  
Followers 0
semedboy

Screen Capture from clipboard

17 posts in this topic

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

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

BTW. There is good and free standalone tool to see and view emf including it's structure.

emfexplorer


The point of world view

Share this post


Link to post
Share on other sites

And why do we need a EMF?

To use the line-art, illustrations and content created in drawing or other applications.

About Windows_Metafile see

here

:mellow:


The point of world view

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

I didn't insulted you.

I'm too. Don't huff!

:mellow:

These EMFes are also the hard task for MS, I think.

See, for example,

here


The point of world view

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

@Yashied:

Thank you.

Try to compare bitmaps from using script with

$oPreview = ObjCreate("Preview.Preview")

and from your one.

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

I'm sorry, though...

:mellow:

Graph.zip


The point of world view

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

The following example works fine, try.

Thanx. Yes, now we have it!

:mellow:


The point of world view

Share this post


Link to post
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
Sign in to follow this  
Followers 0