Je suis tombé il y a peu sur le forum anglais sur un script qui permet de lire les QR code avec une webcam, et je me suis amusé à rajouter cette fonction à l'exemple pour le fun...
Edit,
j'ai un peu retravaillé le script, j'y ai ajouté le détection des caractères interdits pour le nom de fichier, un menu dans le systray pour declencher un aperçu de la capture une fois faite, et l'envoi de la capture dans le buffer, ce qui permet de faire un copier coller direct si on veut.
Bonjour,
Un petit script de capture écran que j'ai fabriqué à partir du sujet suivant : Selecting a rectangle to ScreenCapture qui permet de definir une zone de capture.
Le script tourne en résident et capture la touche PRINTSCREEN, une fois appuyée, la GUI de sélection s'active et permet de définir une zone à capturer. La touche ESCAPE permet de sortir de la boucle.
Une fois faite, la capture est sauvée dans "mes documents" avec le nom définit dans l'inputbox.
Le script se termine (mais reste en résident) en affichant l'image dans le logiciel définit par défaut pour ouvrir les JPG
Tout nouvel appuie sur PRINTSCREEN déclenche le script.
C'est simple mais peut être amélioré.
Voilà le code

#include <Date.au3>
#include <array.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <EditConstants.au3>
#include <Clipboard.au3>
Global $pos, $sfilename_complete
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path
Global Const $IMAGE = $sfilename_complete ; Location of the image file to print
Global $s_ProgramTitle01 = "Select Rectangle"
Global $visionner = False
Global $QRcodeReader = False
FileInstall("---CHEMIN VERS LA DLL---\QRCodeDecodeDll.dll",".\")
HotKeySet("{PRINTSCREEN}","_capture")
Opt("TrayMenuMode",1)
Local $trayMenuLancer = TrayCreateItem("Voir la capture")
Local $trayQRcode = TraycreateItem("Lire QR Code")
TrayItemSetState($trayMenuLancer,4)
TrayItemSetState($trayQRcode,4)
Local $trayMenu = TrayCreateItem ("Quitter")
While 1
$nsystray = TrayGetMsg()
Select
case $nsystray = $trayMenuLancer
If $visionner = False Then
TrayItemSetState($trayMenuLancer,1)
$visionner = True
Else
$visionner = False
TrayItemSetState($trayMenuLancer,4)
EndIf
case $nsystray = $trayMenu
Exit
Case $nsystray = $trayQRcode
If $QRcodeReader = False Then
TrayItemSetState($trayQRcode,1)
$QRcodeReader = True
_capture()
Else
$QRcodeReader = False
TrayItemSetState($trayQRcode,4)
EndIf
EndSelect
sleep(10)
WEnd
Func _capture()
if $QRcodeReader == True Then
Local $aRet = Mark_Rect()
If IsArray($aRet) then
Local $QRFile = @ScriptDir & "\Qrtempfile.bmp"
$hBMP = _ScreenCapture_Capture($QRFile, $iX1, $iY1, $iX2, $iY2, False)
Snapper($QRFile)
FileDelete($QRFile)
$QRcodeReader = False
TrayItemSetState($trayQRcode,4)
EndIf
Else
local $aRet = Mark_Rect()
If IsArray($aRet) then
Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone
$input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
while _CheckForbidden($input_name) <> 0
msgbox (64,"Erreur", "Erreur, le nom comporte des caractères interdits :"& @CRLF & '["/\\*?<>|:]')
$input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
wend
if $input_name="" Then Return
local $sfilename = "capure de " & $input_name
$sfilename_jpg_complete = @MyDocumentsDir & "\" & $sfilename & ".jpg"
$sfilename_bmp_complete = @MyDocumentsDir & "\" & $sfilename & ".bmp"
sleep (500)
; Capture un bitmap 32 bits
$hBMP = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".bmp", $iX1, $iY1, $iX2, $iY2, False)
$hJPG = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".jpg", $iX1, $iY1, $iX2, $iY2, False)
$hClipboard_Bitmap = _WinAPI_LoadImage("",$sfilename_bmp_complete, $IMAGE_BITMAP, $iX2-$iX1,$iy2-$iy1,$LR_LOADFROMFILE)
_ClipBoard_Open(0)
_ClipBoard_Empty()
_ClipBoard_SetDataEx($hClipboard_Bitmap,$CF_BITMAP)
_ClipBoard_Close()
FileDelete($sfilename_bmp_complete)
if not $hClipboard_Bitmap then
Msgbox(64,"Erreur", "Image non capturée")
Else
msgbox(0,"Capture","Le fichier a été copié dans " & $sfilename_jpg_complete & " et placé dans le Presse Papier",2)
if $visionner Then ShellExecute($sfilename_jpg_complete)
EndIf
Else
Return $aRet
EndIf
EndIf
EndFunc ;==> _capture
Func Mark_Rect()
Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
Local $UserDLL = DllOpen("user32.dll")
Local $aRet[4]
; Create transparent GUI with Cross cursor
$hCross_GUI = GUICreate("", @DesktopWidth , @DesktopHeight - 20, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
WinSetTrans($hCross_GUI, "", 8)
GUISetState(@SW_SHOW, $hCross_GUI)
GUISetCursor(3, 1, $hCross_GUI)
Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
GUISetBkColor(0x000000)
; Wait until mouse button pressed
While Not _IsPressed("01", $UserDLL)
Sleep(10)
if _IsPressed("1B", $UserDLL) then
GUIDelete( $hRectangle_GUI)
GUIDelete($hCross_GUI)
DllClose($UserDLL)
$aRet = "ESC"
return $aRet
EndIf
WEnd
; Get first mouse position
$aMouse_Pos = MouseGetPos()
$iX1 = $aMouse_Pos[0]
$iY1 = $aMouse_Pos[1]
; Draw rectangle while mouse button pressed
While _IsPressed("01", $UserDLL)
$aMouse_Pos = MouseGetPos()
$hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
$hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1) ; Bottom of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1]) ; Right of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
; Set overall region
_WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)
If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
Sleep(10)
WEnd
; Get second mouse position
$iX2 = $aMouse_Pos[0]
$iY2 = $aMouse_Pos[1]
; Set in correct order if required
If $iX2 < $iX1 Then
$iTemp = $iX1
$iX1 = $iX2
$iX2 = $iTemp
EndIf
If $iY2 < $iY1 Then
$iTemp = $iY1
$iY1 = $iY2
$iY2 = $iTemp
EndIf
GUIDelete( $hRectangle_GUI)
GUIDelete($hCross_GUI)
DllClose($UserDLL)
$aRet[0] = $iX1
$aRet[1] = $iY1
$aRet[2] = $iX2
$aRet[3] = $iY2
if ($iX2-$iX1)+($iY2-$iY1) < 10 Then
msgbox(0,"Erreur","Capture trop petite : "& ($iX2-$iX1)+($iY2-$iY1) & " Pixel(s), non enregistrée",2)
$aRet = ""
$aRet = "ESC"
EndIf
return $aRet
EndFunc ;==>Mark_Rect
Func _CheckForbidden($string)
Local $pattern_forbid = '["/\\*?<>|:]'
Return StringRegExp($string, $pattern_forbid)
EndFunc
Func Snapper($QR) ; fonction permettant de lire le QR code capturé et le décoder à l'aide de la DLL
Local $hDll = DllOpen(@ScriptDir & '\QRCodeDecodeDll.dll')
Local $Ret = DllCall($hDll, 'ptr', 'QRCodeDecodeImageFile', 'str', $QR, 'int*', 0)
If $Ret[0] Then
Local $data = BinaryToString(StringToBinary(_WinAPI_GetString(DllStructGetData(DllStructCreate('ptr', $Ret[0]), 1), 0), 1), 4)
ClipPut($data)
MsgBox(0,"QR Code",$data & " a été placé dans le Presse Papier",2)
DllCall($hDll, 'none', 'QRCodeFree', 'ptr', $Ret[0], 'int', $Ret[2])
Else
Msgbox(0,"Erreur","Ce n'est pas un QR Code !",3)
EndIf
DllClose($hDll)
EndFunc ;==>Snapper
#include <array.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <EditConstants.au3>
#include <Clipboard.au3>
Global $pos, $sfilename_complete
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path
Global Const $IMAGE = $sfilename_complete ; Location of the image file to print
Global $s_ProgramTitle01 = "Select Rectangle"
Global $visionner = False
Global $QRcodeReader = False
FileInstall("---CHEMIN VERS LA DLL---\QRCodeDecodeDll.dll",".\")
HotKeySet("{PRINTSCREEN}","_capture")
Opt("TrayMenuMode",1)
Local $trayMenuLancer = TrayCreateItem("Voir la capture")
Local $trayQRcode = TraycreateItem("Lire QR Code")
TrayItemSetState($trayMenuLancer,4)
TrayItemSetState($trayQRcode,4)
Local $trayMenu = TrayCreateItem ("Quitter")
While 1
$nsystray = TrayGetMsg()
Select
case $nsystray = $trayMenuLancer
If $visionner = False Then
TrayItemSetState($trayMenuLancer,1)
$visionner = True
Else
$visionner = False
TrayItemSetState($trayMenuLancer,4)
EndIf
case $nsystray = $trayMenu
Exit
Case $nsystray = $trayQRcode
If $QRcodeReader = False Then
TrayItemSetState($trayQRcode,1)
$QRcodeReader = True
_capture()
Else
$QRcodeReader = False
TrayItemSetState($trayQRcode,4)
EndIf
EndSelect
sleep(10)
WEnd
Func _capture()
if $QRcodeReader == True Then
Local $aRet = Mark_Rect()
If IsArray($aRet) then
Local $QRFile = @ScriptDir & "\Qrtempfile.bmp"
$hBMP = _ScreenCapture_Capture($QRFile, $iX1, $iY1, $iX2, $iY2, False)
Snapper($QRFile)
FileDelete($QRFile)
$QRcodeReader = False
TrayItemSetState($trayQRcode,4)
EndIf
Else
local $aRet = Mark_Rect()
If IsArray($aRet) then
Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone
$input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
while _CheckForbidden($input_name) <> 0
msgbox (64,"Erreur", "Erreur, le nom comporte des caractères interdits :"& @CRLF & '["/\\*?<>|:]')
$input_name = Inputbox("Capture","Entrer le nom de la capture écran", "capture-" & StringReplace(_nowtime(),":",""))
wend
if $input_name="" Then Return
local $sfilename = "capure de " & $input_name
$sfilename_jpg_complete = @MyDocumentsDir & "\" & $sfilename & ".jpg"
$sfilename_bmp_complete = @MyDocumentsDir & "\" & $sfilename & ".bmp"
sleep (500)
; Capture un bitmap 32 bits
$hBMP = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".bmp", $iX1, $iY1, $iX2, $iY2, False)
$hJPG = _ScreenCapture_Capture(@MyDocumentsDir & "\" & $sfilename & ".jpg", $iX1, $iY1, $iX2, $iY2, False)
$hClipboard_Bitmap = _WinAPI_LoadImage("",$sfilename_bmp_complete, $IMAGE_BITMAP, $iX2-$iX1,$iy2-$iy1,$LR_LOADFROMFILE)
_ClipBoard_Open(0)
_ClipBoard_Empty()
_ClipBoard_SetDataEx($hClipboard_Bitmap,$CF_BITMAP)
_ClipBoard_Close()
FileDelete($sfilename_bmp_complete)
if not $hClipboard_Bitmap then
Msgbox(64,"Erreur", "Image non capturée")
Else
msgbox(0,"Capture","Le fichier a été copié dans " & $sfilename_jpg_complete & " et placé dans le Presse Papier",2)
if $visionner Then ShellExecute($sfilename_jpg_complete)
EndIf
Else
Return $aRet
EndIf
EndIf
EndFunc ;==> _capture
Func Mark_Rect()
Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
Local $UserDLL = DllOpen("user32.dll")
Local $aRet[4]
; Create transparent GUI with Cross cursor
$hCross_GUI = GUICreate("", @DesktopWidth , @DesktopHeight - 20, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
WinSetTrans($hCross_GUI, "", 8)
GUISetState(@SW_SHOW, $hCross_GUI)
GUISetCursor(3, 1, $hCross_GUI)
Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
GUISetBkColor(0x000000)
; Wait until mouse button pressed
While Not _IsPressed("01", $UserDLL)
Sleep(10)
if _IsPressed("1B", $UserDLL) then
GUIDelete( $hRectangle_GUI)
GUIDelete($hCross_GUI)
DllClose($UserDLL)
$aRet = "ESC"
return $aRet
EndIf
WEnd
; Get first mouse position
$aMouse_Pos = MouseGetPos()
$iX1 = $aMouse_Pos[0]
$iY1 = $aMouse_Pos[1]
; Draw rectangle while mouse button pressed
While _IsPressed("01", $UserDLL)
$aMouse_Pos = MouseGetPos()
$hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
$hMask = _WinAPI_CreateRectRgn($iX1, $aMouse_Pos[1], $aMouse_Pos[0], $aMouse_Pos[1] + 1) ; Bottom of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
$hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1, $aMouse_Pos[1]) ; Right of rectangle
_WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
_WinAPI_DeleteObject($hMask)
; Set overall region
_WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)
If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
Sleep(10)
WEnd
; Get second mouse position
$iX2 = $aMouse_Pos[0]
$iY2 = $aMouse_Pos[1]
; Set in correct order if required
If $iX2 < $iX1 Then
$iTemp = $iX1
$iX1 = $iX2
$iX2 = $iTemp
EndIf
If $iY2 < $iY1 Then
$iTemp = $iY1
$iY1 = $iY2
$iY2 = $iTemp
EndIf
GUIDelete( $hRectangle_GUI)
GUIDelete($hCross_GUI)
DllClose($UserDLL)
$aRet[0] = $iX1
$aRet[1] = $iY1
$aRet[2] = $iX2
$aRet[3] = $iY2
if ($iX2-$iX1)+($iY2-$iY1) < 10 Then
msgbox(0,"Erreur","Capture trop petite : "& ($iX2-$iX1)+($iY2-$iY1) & " Pixel(s), non enregistrée",2)
$aRet = ""
$aRet = "ESC"
EndIf
return $aRet
EndFunc ;==>Mark_Rect
Func _CheckForbidden($string)
Local $pattern_forbid = '["/\\*?<>|:]'
Return StringRegExp($string, $pattern_forbid)
EndFunc
Func Snapper($QR) ; fonction permettant de lire le QR code capturé et le décoder à l'aide de la DLL
Local $hDll = DllOpen(@ScriptDir & '\QRCodeDecodeDll.dll')
Local $Ret = DllCall($hDll, 'ptr', 'QRCodeDecodeImageFile', 'str', $QR, 'int*', 0)
If $Ret[0] Then
Local $data = BinaryToString(StringToBinary(_WinAPI_GetString(DllStructGetData(DllStructCreate('ptr', $Ret[0]), 1), 0), 1), 4)
ClipPut($data)
MsgBox(0,"QR Code",$data & " a été placé dans le Presse Papier",2)
DllCall($hDll, 'none', 'QRCodeFree', 'ptr', $Ret[0], 'int', $Ret[2])
Else
Msgbox(0,"Erreur","Ce n'est pas un QR Code !",3)
EndIf
DllClose($hDll)
EndFunc ;==>Snapper