1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
| Option Explicit
Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hdc As LongPtr, ByVal nIndex As Long) As Long
Private Declare PtrSafe Function GetWindowDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As LongPtr) As LongPtr
Private Declare PtrSafe Function CreateDIBSection Lib "gdi32" (ByVal hdc As LongPtr, pBitmapInfo As BitmapInfo, ByVal un As Long, ByVal lplpVoid As LongPtr, ByVal handle As LongPtr, ByVal dw As Long) As LongPtr
Private Declare PtrSafe Function SelectObject Lib "gdi32" (ByVal hdc As LongPtr, ByVal hObject As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function BitBlt Lib "gdi32" (ByVal hDestDC As LongPtr, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As LongPtr, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare PtrSafe Function GetDIBits Lib "gdi32" (ByVal aHDC As LongPtr, ByVal hBitmap As LongPtr, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BitmapInfo, ByVal wUsage As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type BitmapInfo
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biRUsed As Long
biRImportant As Long
End Type
Private Type BitMapFileHeader
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
'------------------------------------------------------------------------------------------------
Public Sub UserFormEnImage(StrNomDuFichier As String, ObjFormulaire As Object, _
Optional ByVal HauteurMaxi As Long = 0, _
Optional ByVal LargeurMaxi As Long = 0, _
Optional Zoom As Integer = 100)
'------------------------------------------------------------------------------------------------
' Copie un formulaire en fichier BMP, GIF, JPG, PNG, TIF
'------------------------------------------------------------------------------------------------
' StrNomDuFichier : Non du fichier à générer avec son chemin (valide) et son extension.
' ObjFormulaire : Nom du formulaire.
' HauteurMaxi : Si différent de 0 la hauteur maxi en pixel (le ratio est conservé).
' LargeurMaxi : Si différent de 0 la largeur maxi en pixel (le ratio est conservé).
' Zoom : Le Zoom à appliquer, 100 = 100%.
'------------------------------------------------------------------------------------------------
Dim X1 As Long, Y1 As Long, X2 As Long, Y2 As Long
Dim Irect As RECT
Dim lngLargeur As Long, lngHauteur As Long
Dim lngHdc As LongPtr
Dim lngHBmp As LongPtr
Dim bmiBitmapInfo As BitmapInfo
Dim bmfBitmapFileHeader As BitMapFileHeader
Dim lngFnum As Integer
Dim pixels() As Byte
Dim Fichier As String
Const Marge As Integer = 9 ' A adapter au contexte...
' Contrôle l'extension du fichier:
Select Case UCase(Right(StrNomDuFichier, 4))
Case ".BMP", ".GIF", ".JPG", ".PNG", ".TIF"
' Création d'un ficher temporaire sur le profile de l'utilisateur:
Fichier = Environ("USERPROFILE") & "\" & Int(Timer * 100) & Date & ".BMP"
Fichier = Replace(Fichier, "/", "")
Case Else: MsgBox "L'extension du fichier " & StrNomDuFichier & " n'est pas reconnue par cette fonction.": Exit Sub
End Select
' Détermine la position du formulaire avec une marge de 9 points pour les formulaires aux bords arrondis,
' marge à ajuster si besoin, suivant les versions Windows:
X1 = PointsEnPixelsX(ObjFormulaire.Left) + Marge
Y1 = PointsEnPixelsY(ObjFormulaire.Top) + Marge
X2 = X1 + PointsEnPixelsX(ObjFormulaire.Width) - Marge * 2
Y2 = Y1 + PointsEnPixelsY(ObjFormulaire.Height) - Marge * 2
lngHauteur = Y2 - Y1
lngLargeur = X2 - X1
' Crée un bitmap vierge:
With bmiBitmapInfo
.biBitCount = 32
.biCompression = 0&
.biPlanes = 1
.biSize = Len(bmiBitmapInfo)
.biHeight = lngHauteur
.biWidth = lngLargeur
.biSizeImage = ((((.biWidth * .biBitCount) + 31) \ 32) * 4 - (((.biWidth * .biBitCount) + 7) \ 8)) * .biHeight
End With
lngHdc = CreateCompatibleDC(0)
lngHBmp = CreateDIBSection(lngHdc, bmiBitmapInfo, 0&, ByVal 0&, ByVal 0&, ByVal 0&)
Call SelectObject(lngHdc, lngHBmp)
' Copie la partie de l'écran demandée:
Call BitBlt(lngHdc, 0, 0, lngLargeur, lngHauteur, GetDC(GetDesktopWindow()), X1, Y1, &HCC0020) ' &HCC0020=SRCCOPY
' Crée l'entête du fichier bmp:
With bmfBitmapFileHeader
.bfType = &H4D42&
.bfOffBits = Len(bmfBitmapFileHeader) + Len(bmiBitmapInfo)
.bfSize = .bfOffBits + bmiBitmapInfo.biSizeImage
End With
' Lit les bits du bitmap et les place dans le tableau de pixels:
ReDim pixels(1 To 4, 1 To lngLargeur, 1 To lngHauteur)
Call GetDIBits(lngHdc, lngHBmp, 0, lngHauteur, pixels(1, 1, 1), bmiBitmapInfo, 0&) ' 0&)=DIB_RGB_COLORS
' Demande un numéro temporaire de fichier:
lngFnum = FreeFile
On Error Resume Next
Kill StrNomDuFichier
Kill Fichier
' Crée le fichier:
Open Fichier For Binary As lngFnum
' Ecrit l'entête:
Put #lngFnum, , bmfBitmapFileHeader
' Ecrit les informations du bitmap:
Put #lngFnum, , bmiBitmapInfo
' Ecrit les bits de l'image:
Put #lngFnum, , pixels
' Ferme le fichier si ouvert:
Close lngFnum
' Redimensionne l'image:
If HauteurMaxi <> 0 Or LargeurMaxi <> 0 Or Zoom <> 100 Then
If HauteurMaxi = 0 Then HauteurMaxi = lngHauteur
If LargeurMaxi = 0 Then LargeurMaxi = lngLargeur
If Zoom <> 100 Then HauteurMaxi = HauteurMaxi * (Zoom / 100): LargeurMaxi = LargeurMaxi * (Zoom / 100)
Call RedimensionnerImage(Fichier, Fichier, HauteurMaxi, LargeurMaxi)
End If
' Change le format du fichier suivant l'extension désirée:
Dim Anc As String
Select Case UCase(Right(StrNomDuFichier, 4))
Case ".GIF", ".JPG", ".PNG", ".TIF"
Anc = Fichier
Fichier = Left(Fichier, Len(Fichier) - 4) & Right(StrNomDuFichier, 4)
Call ConvertirImage(Anc, Fichier)
End Select
' Déplace le fichier temporaire dans sa destination désirée:
Name Fichier As StrNomDuFichier
Err.Clear
End Sub
'------------------------------------------------------------------------------------------------
Private Function PointsEnPixelsX(lPoint As Long) As Long
'------------------------------------------------------------------------------------------------
Static Mult As Single
If Mult = 0 Then Mult = 72 / GetDeviceCaps(GetWindowDC(0), 88) ' LOGPIXELSX
PointsEnPixelsX = CLng(lPoint / Mult)
End Function
'------------------------------------------------------------------------------------------------
Private Function PointsEnPixelsY(lPoint As Long) As Long
'------------------------------------------------------------------------------------------------
Static Mult As Single
If Mult = 0 Then Mult = 72 / GetDeviceCaps(GetWindowDC(0), 90) ' LOGPIXELSY
PointsEnPixelsY = CLng(lPoint / Mult)
End Function
'---------------------------------------------------------------------------------------
Private Function RedimensionnerImage(ImageSource As String, ImageDestination As String, _
HauteurMaxi As Long, LargeurMaxi As Long) As Boolean
'---------------------------------------------------------------------------------------
' Redimensionne une image.
' remarque : Les proportions sont conservées. Le filtre prend en compte
' les ratios et adapte la taille pour ne pas dépasser les valeurs maxi définies.
'---------------------------------------------------------------------------------------
' Source: https://silkyroad.developpez.com/VBA/WindowsImageAcquisition/
'---------------------------------------------------------------------------------------
Dim Img As Object, IP As Object
' Gestion des erreurs:
On Error GoTo Gest_Err
Err.Clear
'Création conteneur pour l'image à manipuler:
Set Img = CreateObject("WIA.ImageFile")
'Création du gestionnaire de filtre:
Set IP = CreateObject("WIA.ImageProcess")
'Chargement de l'image dans le conteneur:
Img.LoadFile ImageSource
'Ajoute le filtre pour redimensionner l'image (Scale):
IP.Filters.Add IP.FilterInfos("Scale").FilterID
'Définit la largeur maxi pour le redimensionnement:
IP.Filters(1).Properties("MaximumWidth") = LargeurMaxi
'Définit la hauteur maxi pour le redimensionnement:
IP.Filters(1).Properties("MaximumHeight") = HauteurMaxi
' Application du filtre à l'image:
Set Img = IP.Apply(Img)
'Enregistre l'image redimensionnée:
If Dir(ImageDestination) <> "" Then Kill ImageDestination
Img.SaveFile ImageDestination
RedimensionnerImage = True
' Gestion des erreurs:
Gest_Err:
If Err.Number <> 0 Then MsgBox "Erreur: " & Err.Number & " - " & Err.Description, _
vbCritical + vbOKOnly, "RedimensionnerImage"
Err.Clear
End Function
'---------------------------------------------------------------------------------------
Private Function ConvertirImage(ImageSource As String, ImageDestination As String, _
Optional Qualité As Integer = 100) As Boolean
'---------------------------------------------------------------------------------------
' Convertit une image source en BMP, GIF, JPG, PNG, TIF
' L'extension de l'image destination indique le format à appliquer.
'---------------------------------------------------------------------------------------
' Exemple pour convertir une image BMP en JPG:
' Call ConvertirImage("C:\_Temporaire\foret.bmp", "C:\_Temporaire\foret.jpg")
'---------------------------------------------------------------------------------------
' Sources: https://silkyroad.developpez.com/VBA/WindowsImageAcquisition/
' https://www.devhut.net/vba-wia-convert-the-image-format/
'---------------------------------------------------------------------------------------
Dim Img As Object, IP As Object
Dim FormatID As String
' Gestion des erreurs:
On Error GoTo Gest_Err
Err.Clear
' Le format à appliquer est déduit de l'extension du fichier image destination:
Select Case UCase(Right(ImageDestination, 4))
Case ".BMP": FormatID = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
Case ".JPG": FormatID = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
Case ".GIF": FormatID = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
Case ".PNG": FormatID = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
Case ".TIF": FormatID = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"
Case Else
Err.Raise vbObjectError, , "L'extension du fichier image destination [" & ImageDestination & "] n'est pas reconnue."
End Select
' Création conteneur pour l'image à manipuler:
Set Img = CreateObject("WIA.ImageFile")
' Création du gestionnaire de filtre:
Set IP = CreateObject("WIA.ImageProcess")
' Chargement de l'image dans le conteneur:
Img.LoadFile ImageSource
' Ajoute le filtre pour convertir l'image (Convert):
IP.Filters.Add IP.FilterInfos("Convert").FilterID
' Définit le format:
IP.Filters(1).Properties("FormatID") = FormatID
' Définit la qualité:
If Qualité < 1 Or Qualité > 100 Then Qualité = 100
IP.Filters(1).Properties("Quality") = Qualité
' Application du filtre à l'image:
Set Img = IP.Apply(Img)
' Enregistre l'image:
If Dir(ImageDestination) <> "" Then Kill ImageDestination
Img.SaveFile ImageDestination
ConvertirImage = True
' Gestion des erreurs:
Gest_Err:
If Err.Number <> 0 Then MsgBox "Erreur: " & Err.Number & " - " & Err.Description, _
vbCritical + vbOKOnly, "ConvertirImage"
Err.Clear
End Function
'------------------------------------------------------------------------------------------------
'------------------------------------------------------------------------------------------------ |