[..] Extraire les images du presse-papiers

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

[..] Extraire les images du presse-papiers

#1

Message par jpascal »

Bonjour,

J'essaie tant bien que mal de comprendre les fonctions de clipboard.au3

Je souhaiterais dans un premier temps extraire les images de mon presse-papiers.

Je copie au préalable du texte et une image à partir d'un site internet.
J'appuie sur F7 pour afficher le contenu du presse-papiers.
J'appuie sur F8 pour tenter d'afficher le contenu bitmap.
J'arrive à voir qu'il y a du contenu bitmap mais je ne sais pas comment afficher sa "valeur" en binaire.

Pourriez-vous m'apporter un peu d'aide ?
#Region Includes
#include <Clipboard.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <MsgBoxConstants.au3>
#include <SendMessage.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
#include <_Perso.au3>
#EndRegion Includes

#Region Variables
Global $g_aFormat[0]
Global $g_vText, $g_vBitmap

Global $g_idEdit = 0
#EndRegion Variables

HotKeySet('{F7}', "CopyToClipboard")
HotKeySet('{F8}', "PasteFromClipboard")

Main()

Func Main()
   _Singleton(@ScriptName, 0)

   Local $hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), 400, 400, 10, 10, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX), $WS_EX_TOPMOST)
   $g_idEdit = GUICtrlCreateEdit('', 0, 0, 400, 400, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
   GUISetState(@SW_SHOW)

   _WinAPI_AddClipboardFormatListener($hForm)
   _SendMessage($hForm, $WM_CLIPBOARDUPDATE)

   Do
   Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>Main


Func CopyToClipboard()
   ReDim $g_aFormat[0][2]
   Local $iFormat = 0, $iCount = 0

   _ClipBoard_Open(0)
   MemoWrite("Clipboard formats : " & _ClipBoard_CountFormats())
   Do
      $iFormat = _ClipBoard_EnumFormats($iFormat)
      If $iFormat <> 0 Then
         $iCount += 1
         MemoWrite("Clipboard format " & $iCount & " : " & _ClipBoard_FormatStr($iFormat))
         Switch $iFormat
            Case $CF_TEXT
               $g_vText = _ClipBoard_GetData($iFormat)
            Case $CF_BITMAP
               $g_vBitmap = _ClipBoard_GetData($iFormat)
         EndSwitch
;~          _ArrayAdd($g_aFormat, $iFormat, _ClipBoard_GetData($iFormat))
      EndIf
   Until $iFormat = 0

;~    For $i = 0 To UBound($g_aFormat) - 1
;~       MemoWrite(_ClipBoard_FormatStr($g_aFormat[$i][0]) & @CRLF & $g_aFormat[$i][1] & @CRLF & @CRLF)
;~    Next
   _ClipBoard_Close()
EndFunc   ;==>CopyToClipboard

Func PasteFromClipboard()
;~    _ClipBoard_SetData($g_vText, $CF_TEXT)
   _ClipBoard_SetData($g_vBitmap, $CF_BITMAP)
   MemoWrite($g_vBitmap & @CRLF)
EndFunc   ;==>PasteFromClipboard

Func MemoWrite($sMessage = "")
   GUICtrlSetData($g_idEdit, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#2

Message par walkson »

Bonjour,
Quelque chose comme ça ?

Code : Tout sélectionner

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Clipboard.au3>
#include <WinAPIHObj.au3>
#include <SendMessage.au3>

#Region ### START Koda GUI section ### Form=
Global $Form1 = GUICreate("Form1", 471, 438, 192, 124,-1,$WS_EX_TOPMOST)
Global $Label1 = GUICtrlCreatePic("", 25, 34, 420, 370, $SS_BITMAP)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
$origHWND = DLLCall("user32.dll","int","AddClipboardFormatListener","hwnd",$Form1)
$origHWND = $origHWND[0]
GUIRegisterMsg($WM_CLIPBOARDUPDATE, "WM_CLIPBOARDUPDATE")
While 1
 $nMsg = GUIGetMsg()
 Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
 EndSwitch
WEnd
Func WM_CLIPBOARDUPDATE($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	$handle = _ClipBoard_GetOwner( )
	_ClipBoard_Open($handle)
	$binary = _ClipBoard_GetDataEx($CF_BITMAP)
	$path = ClipGet()
	If FileExists($path) = 1 Then
		image($path,1);option 1 par le chemin
	Else
		image($binary,2);option 2 par le handle de l'image
	EndIf

	_ClipBoard_Close ( )


EndFunc   ;==>WM_CLIPBOARDUPDATE
Func image($binary, $option)

	_GDIPlus_Startup()
	If $option = 1 Then $hBitmap = _GDIPlus_BitmapCreateFromFile($binary)
	If $option = 2 Then $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($binary)
	$hBitmap = _GDIPlus_ImageResize($hBitmap, 420, 370)
	$hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
	ConsoleWrite("---" & $hBMP & @CRLF)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_Shutdown()
	_SendMessage(GUICtrlGetHandle($Label1), $STM_SETIMAGE, $IMAGE_BITMAP, 0)
	_WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($Label1), $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP))
	_WinAPI_DeleteObject($hBMP)
EndFunc
Le code se met en attente d'une copie d'image (ctrl+c ou autres)
De copier une image sur le web, ou affichée dans un logiciel de dessin ou copier une image dans un de vos dossiers fonctionne aussi
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#3

Message par jpascal »

Bonjour walkson,

Mieux vaut tard que jamais paraît-il, je vous remercie donc pour ce bout de code. :-)

En y ajoutant la ligne suivante (et l'include) :

Code : Tout sélectionner

_ScreenCapture_SaveImage('c:\temp\Image.bmp', $hBMP, True)
je peux donc enregistrer le fichier correspondant à l'image collée dans le PP (presse-papiers).

Je peux désormais exposer le problème qui me fait m'intéresser aux fonctions liées au PP à moins que vous ne souhaitiez que j'ouvre un nouveau sujet pour cela.
Lorsque je copie dans le PP une image affichée dans un mail, si je la colle dans un éditeur d'un CMS (site web), l'image n'est pas collée.
Si je colle l'image dans Word ou un éditeur de notes comme Evernote, puis que je copie l'image du logiciel dans le PP, alors je peux la coller dans le CMS.

Avec le script modifié, j'ai créé deux fichiers images, le premier provenant du client mail, le second de l'image copiée dans Word à partir du client mail.
Je m'aperçois que les fichiers sont identiques.
J'en déduis donc que la donnée est la même, le contraire eut été étonnant, mais que la structure est différente.

Pouvez-vous m'aiguiller pour que je puisse analyser la structure du PP dans les deux cas ?
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Clipboard.au3>
#include <WinAPIHObj.au3>
#include <SendMessage.au3>

#include <ScreenCapture.au3>

#Region ### START Koda GUI section ### Form=
Global $Form1 = GUICreate("Form1", 471, 438, 192, 124, -1, $WS_EX_TOPMOST)
Global $Label1 = GUICtrlCreatePic("", 25, 34, 420, 370, $SS_BITMAP)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

$origHWND = DllCall("user32.dll", "int", "AddClipboardFormatListener", "hwnd", $Form1)
$origHWND = $origHWND[0]
GUIRegisterMsg($WM_CLIPBOARDUPDATE, "WM_CLIPBOARDUPDATE")

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit
   EndSwitch
WEnd

Func WM_CLIPBOARDUPDATE($hWnd, $iMsg, $wParam, $lParam)
   #forceref $hWnd, $iMsg

   $handle = _ClipBoard_GetOwner()
   _ClipBoard_Open($handle)
   $binary = _ClipBoard_GetDataEx($CF_BITMAP)
   $path = ClipGet()
   If FileExists($path) = 1 Then
      image($path, 1) ;option 1 par le chemin
   Else
      image($binary, 2) ;option 2 par le handle de l'image
   EndIf

   _ClipBoard_Close()
EndFunc   ;==>WM_CLIPBOARDUPDATE

Func image($binary, $option)
   ConsoleWrite('Option ' & $option & @CRLF)
   ConsoleWrite($binary & @CRLF)

   _GDIPlus_Startup()
   If $option = 1 Then $hBitmap = _GDIPlus_BitmapCreateFromFile($binary)
   If $option = 2 Then $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($binary)
   $hBitmap = _GDIPlus_ImageResize($hBitmap, 420, 370)
   $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
   ConsoleWrite("---" & $hBMP & @CRLF)
   _GDIPlus_BitmapDispose($hBitmap)
   _GDIPlus_Shutdown()

   _SendMessage(GUICtrlGetHandle($Label1), $STM_SETIMAGE, $IMAGE_BITMAP, 0)
   _ScreenCapture_SaveImage('c:\temp\_Image.bmp', $hBMP, True) ; True -> $hBMP destroyed

   _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($Label1), $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP))
   _WinAPI_DeleteObject($hBMP)
EndFunc   ;==>image
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#4

Message par jpascal »

Je me réponds à moi-même.

Si j'utilise la fonction _ClipBoard_EnumFormats(), je vois les différences.
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Clipboard.au3>
#include <WinAPIHObj.au3>
#include <SendMessage.au3>

#include <ScreenCapture.au3>

GUIRegisterMsg($WM_CLIPBOARDUPDATE, "WM_CLIPBOARDUPDATE")

; Create GUI
$hGUI = GUICreate("Clipboard", 600, 400)
$g_idMemo = GUICtrlCreateEdit("", 2, 2, 596, 396, $WS_VSCROLL)
GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New")
GUISetState(@SW_SHOW)

While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit
   EndSwitch
WEnd

Func WM_CLIPBOARDUPDATE($hWnd, $iMsg, $wParam, $lParam)
   #forceref $hWnd, $iMsg

   Local $hGUI, $iFormat, $iCount

   $handle = _ClipBoard_GetOwner()
   _ClipBoard_Open($handle)

   ; Show clipboard formats available
   GUICtrlSetData($g_idMemo, '')
   MemoWrite("Clipboard formats ..: " & _ClipBoard_CountFormats())

   ; Enumerate clipboard formats
   Do
      $iFormat = _ClipBoard_EnumFormats($iFormat)
      If $iFormat <> 0 Then
         $iCount += 1
         MemoWrite("Clipboard format " & $iCount & " .: " & _ClipBoard_FormatStr($iFormat))
      EndIf
   Until $iFormat = 0

   $binary = _ClipBoard_GetDataEx($CF_BITMAP)
   $path = ClipGet()
   If FileExists($path) = 1 Then
      image($path, 1) ;option 1 par le chemin
   Else
      image($binary, 2) ;option 2 par le handle de l'image
   EndIf

   _ClipBoard_Close()
EndFunc   ;==>WM_CLIPBOARDUPDATE

Func image($binary, $option)
   ConsoleWrite('Option ' & $option & @CRLF)
   ConsoleWrite($binary & @CRLF)

   _GDIPlus_Startup()
   If $option = 1 Then $hBitmap = _GDIPlus_BitmapCreateFromFile($binary)
   If $option = 2 Then $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($binary)
   $hBitmap = _GDIPlus_ImageResize($hBitmap, 420, 370)
   $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
   ConsoleWrite("---" & $hBMP & @CRLF)
   _GDIPlus_BitmapDispose($hBitmap)
   _GDIPlus_Shutdown()

   _ScreenCapture_SaveImage('c:\temp\_Image.bmp', $hBMP, True) ; True -> $hBMP destroyed
   _WinAPI_DeleteObject($hBMP)
EndFunc   ;==>image

; Write message to memo
Func MemoWrite($sMessage = "")
   GUICtrlSetData($g_idMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite

Copie à partir du client mail :
Clipboard formats ..: 21
Clipboard format 1 .: DataObject
Clipboard format 2 .: Object Descriptor
Clipboard format 3 .: Rich Text Format
Clipboard format 4 .: HTML Format
Clipboard format 5 .: Enhanced Metafile
Clipboard format 6 .: Metafile Picture
Clipboard format 7 .: PNG
Clipboard format 8 .: JFIF
Clipboard format 9 .: GIF
Clipboard format 10 .: ActiveClipBoard
Clipboard format 11 .: PNG+Office Art
Clipboard format 12 .: GIF+Office Art
Clipboard format 13 .: JFIF+Office Art
Clipboard format 14 .: Office Drawing Shape Format
Clipboard format 15 .: DIB
Clipboard format 16 .: Bitmap
Clipboard format 17 .: Embed Source
Clipboard format 18 .: Native
Clipboard format 19 .: OwnerLink
Clipboard format 20 .: Ole Private Data
Clipboard format 21 .: DIB V5

Copie à partir de Word :
Clipboard formats ..: 13
Clipboard format 1 .: DataObject
Clipboard format 2 .: Art::GVML ClipFormat
Clipboard format 3 .: PNG
Clipboard format 4 .: GIF
Clipboard format 5 .: Enhanced Metafile
Clipboard format 6 .: Metafile Picture
Clipboard format 7 .: Bitmap
Clipboard format 8 .: JFIF
Clipboard format 9 .: Object Descriptor
Clipboard format 10 .: image/svg+xml
Clipboard format 11 .: Ole Private Data
Clipboard format 12 .: DIB
Clipboard format 13 .: DIB V5

J'ai donc un de ces formats qui posent problèmes pour le collage de l'image :
Clipboard format .: Object Descriptor
Clipboard format .: Rich Text Format
Clipboard format .: HTML Format
Clipboard format .: ActiveClipBoard
Clipboard format .: PNG+Office Art
Clipboard format .: GIF+Office Art
Clipboard format .: JFIF+Office Art
Clipboard format .: Office Drawing Shape Format
Clipboard format .: Embed Source
Clipboard format .: Native
Clipboard format .: OwnerLink
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#5

Message par jpascal »

J'ai tenté de remplacer le contenu du presse-papiers uniquement par une image au format Bitmap... sans succès.

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Clipboard.au3>
#include <WinAPIHObj.au3>
#include <SendMessage.au3>

#include <ScreenCapture.au3>

; Create GUI
$hGUI = GUICreate("Clipboard", 500, 600, 0, 0)
WinSetOnTop($hGUI, "", 1)
$g_idMemo = GUICtrlCreateEdit("", 2, 2, 496, 596, $WS_VSCROLL)
GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New")
GUISetState(@SW_SHOW)

$origHWND = DllCall("user32.dll", "int", "AddClipboardFormatListener", "hwnd", $hGUI)
$origHWND = $origHWND[0]
GUIRegisterMsg($WM_CLIPBOARDUPDATE, "WM_CLIPBOARDUPDATE")


While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
      Case $GUI_EVENT_CLOSE
         Exit
   EndSwitch
WEnd

Func WM_CLIPBOARDUPDATE($hWnd, $iMsg, $wParam, $lParam)
   #forceref $hWnd, $iMsg

   Local $hGUI, $iFormat, $iCount

   $handle = _ClipBoard_GetOwner()
   _ClipBoard_Open($handle)

   ; Show clipboard formats available
   GUICtrlSetData($g_idMemo, '')

   If _ClipBoard_EnumFormats($CF_BITMAP) = 0 Then ; No bitmap
      _ClipBoard_Close()
      Return
   EndIf

   MemoWrite("Clipboard formats ..: " & _ClipBoard_CountFormats())
   ; Enumerate clipboard formats
   Do
      $iFormat = _ClipBoard_EnumFormats($iFormat)
      If $iFormat <> 0 Then
         $iCount += 1
         MemoWrite("Clipboard format " & $iCount & " .: " & _ClipBoard_FormatStr($iFormat))
      EndIf
   Until $iFormat = 0

   $binary = _ClipBoard_GetDataEx($CF_BITMAP)

   _GDIPlus_Startup()
   $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($binary)
   $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
   ConsoleWrite("---" & $hBMP & @CRLF)
   _GDIPlus_BitmapDispose($hBitmap)
   _GDIPlus_Shutdown()

;~    _ScreenCapture_SaveImage('c:\temp\_Image.bmp', $hBMP, True) ; True -> $hBMP destroyed

   _ClipBoard_Close()

   ; = Modification du presse-papiers =
   MemoWrite("")
   MemoWrite("Tentative de modification du presse-papiers dans 3 secondes")
   Sleep(3000)
   _ClipBoard_SetDataEx($hBMP, $CF_BITMAP)

   ; = Nouvelle analyse =
   GUICtrlSetData($g_idMemo, '')

   _ClipBoard_Open($handle)
   $iCount = 0
   MemoWrite("Clipboard formats ..: " & _ClipBoard_CountFormats())
   Do
      $iFormat = _ClipBoard_EnumFormats($iFormat)
      If $iFormat <> 0 Then
         $iCount += 1
         MemoWrite("Clipboard format " & $iCount & " .: " & _ClipBoard_FormatStr($iFormat))
      EndIf
   Until $iFormat = 0

   $binary = _ClipBoard_GetDataEx($CF_BITMAP)
   _GDIPlus_Startup()
   $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($binary)
   $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
   ConsoleWrite("---" & $hBMP & @CRLF)
   _GDIPlus_BitmapDispose($hBitmap)
   _GDIPlus_Shutdown()

   _WinAPI_DeleteObject($hBMP)
EndFunc   ;==>WM_CLIPBOARDUPDATE

; Write message to memo
Func MemoWrite($sMessage = "")
   GUICtrlSetData($g_idMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 2086
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#6

Message par TommyDDR »

Suite du feuilleton dans 1an ! :P
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
jpascal
Niveau 6
Niveau 6
Messages : 226
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#7

Message par jpascal »

J'ose espérer qu'un expert aura pitié de moi bien avant. 😅
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [..] Extraire les images du presse-papiers

#8

Message par walkson »

Bonjour,
Vous tournez en rond dans votre code (sans parler des erreurs)
$binary = _ClipBoard_GetDataEx($CF_BITMAP) renvoie un bitmap windows à l'identique de
$hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
Pour faire court, il y a les bitmaps windows ($Hbmp) et les bitmaps de GDIplus
Mais je pense (mais je peux me tromper) que le problème vient d'ailleurs et qu'il faut utiliser l'image en binaire encodée par du base64. Essayez de coller cette ligne dans votre CMS
<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzEAAAAAXNSR0IArs4c6QAAAARnQU1B
AACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAhSURBVDhPY6yS+f+fgQLABKXJBqMG
jBoAAqMGDAMDGBgAZ4ACtmuQ2cwAAAAASUVORK5CYII="
alt="AAA" />
et dites moi le résultat
Normalement vous devriez obtenir un petit rectangle bleu........
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Répondre