forked from Drugoy/Autohotkey-scripts-.ahk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SilentScreenshotter(+upload).ahk
455 lines (436 loc) · 18.9 KB
/
SilentScreenshotter(+upload).ahk
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
/* SilentScreenshooter v1.9
Last modified: 2016.01.12 18:10
This script takes *.png screenshots of the specified area and uploads them to imgur.com and depending on user's setting - it either stores the URL of the uploaded image into the clipboard or opens it instantly. It also supports image files to be drag'n'dropped onto the script to upload them.
Script author: Drugoy a.k.a. Drugmix
Contacts: [email protected], [email protected]
https://github.com/Drugoy/Autohotkey-scripts-.ahk/tree/master/SilentScreenshotter/
Thanks to: maestrith, GeekDude.
Requirements:
0. Some very basic .ahk knowledge for one-time script configuration.
1. That requirement is optional: 'Optipng' utility: it is boundled along with this script If the script is compiled, or can be downloaded from here: http://optipng.sourceforge.net/
2. AHK_L x32 Unicode. The script may not work with other versions.
How to use:
1. Obtain ClientID here: https://api.imgur.com/oauth2/addclient
2. Configure the settings.
3. Run the script.
4. a. Set cursor at any corner of the area you'd like to take a screenshot of.
b. Hit [PrintScreen].
c. Set cursor to the opposite corner.
d. Either hit [PrintScreen] again or [left click] to lock the area to be screenshooted.
e. Hit [PrintScreen] once again to finally take the screenshot.
Before step "4e" - you may cancel screenshooting process by hitting Escape button.
*/
;{ Initialization before settings
#SingleInstance, Off
#NoEnv
SetWorkingDir, %A_ScriptDir%
FileInstall, optipng.exe, optipng.exe
CoordMode, Mouse
CoordMode, Pixel
SetBatchLines, -1
Hotkey, $Esc,, Off
OnExit, Exit
;}
;{ Settings
If (A_IsCompiled)
{
IfNotExist, settings.ini
{
IniWrite,
(
; UNCOMMENT LINES TO MAKE THEM GET READ
; Paste here your imgur's client ID that can be obtained for free (registration is required, but you may use fake email) here: https://api.imgur.com/oauth2/addclient
imgurClientID=
; Specify path and screenshot's name.
;imgPath=`%A_Temp`%\
; Specify locally saved image's name. Default name is the date stamp (with time).
;imgName=`%A_Now`%
; Specify desired file format (most of common formats are supported).
;imgExtension=png
; Use values from 0 to 7 to specify the compression level: 0 = no compression, 7 = max compression. Compression is always lossless, but works only for PNG.
;optimizePNG=7
; Specify path to "optipng.exe" If you would like to use it.
;optipngPath=`%A_ScriptDir`%\optipng.exe
; 0 = the image's URL will be opened in browser; 1 = copy to clipboard; 2 = do both.
;clipURL=1
; 0 = the local screenshot won't get deleted after it got uploaded to the server, 1 = it will be removed as soon as the file got uploaded to the server.
;tempScreenshot=1
; Use values from 0 to 100 to specify quality for screenshots in JPEG (by default PNG is used).
;jpgQuality=100
), settings.ini, settings
}
IniRead, imgurClientID, settings.ini, settings, imgurClientID
IniRead, imgPath, settings.ini, settings, imgPath, % A_Temp "\"
IniRead, imgName, settings.ini, settings, imgName, % A_Now
IniRead, imgExtension, settings.ini, settings, imgExtension, png
IniRead, optimizePNG, settings.ini, settings, optimizePNG, 7
IniRead, optipngPath, settings.ini, settings, optipngPath, % A_ScriptDir "\optipng.exe"
IniRead, clipURL, settings.ini, settings, clipURL, 1
IniRead, tempScreenshot, settings.ini, settings, tempScreenshot, 1
IniRead, jpgQuality, settings.ini, settings, jpgQuality, 100
}
Else
{
imgPath := A_Temp "\" ; Specify path and screenshot's name.
imgName := A_Now ; Specify locally saved image's name. Default name is the date stamp (with time).
imgExtension := "png" ; Specify desired file format (most of common formats are supported).
optimizePNG := 0 ; Use values from 0 to 7 to specify the compression level: 0 = no compression, 7 = max compression. Compression is always lossless, but works only for PNG.
optipngPath := A_ScriptDir "\optipng.exe" ; Specify path to "optipng.exe" If you would like to use it.
clipURL := 2 ; 0 = the image's URL will be opened in browser; 1 = copy to clipboard; 2 = do both.
tempScreenshot := 0 ; 0 = the local screenshot won't get deleted after it got uploaded to the server, 1 = it will be removed as soon as the file got uploaded to the server.
imgurClientID := "a6f3e91e6977dc8" ; Paste here your imgur's client ID that can be obtained for free (registration is required, but you may use fake email) here: https://api.imgur.com/oauth2/addclient
jpgQuality := 100 ; Use values from 0 to 100 to specify quality for screenshots in JPEG (by default PNG is used).
; ListLines, Off ; Uncomment this if the script is fully working for you and you'd like to save a bit of RAM by sacrificing script's self-debugging ability.
}
;}
If !(imgurClientID) ; The script can't work without imgurClientID.
{
MsgBox, 'imgurClientID' is empty`, you should obtain it and paste into the script or .ini file.`nOpening https://api.imgur.com/oauth2/addclient so you can register there and obtain imgurClientID.`nHint: you may use fake email at registration.
Run, https://api.imgur.com/oauth2/addclient
ExitApp
}
Global imgurClientID, proxyEnable, proxyServer, clipURL, tempScreenshot, uploadProgress
Global ptr := A_PtrSize ? "UPtr" : "UInt"
targetToUpload := []
RegRead, proxyEnable, HKCU, Software\Microsoft\Windows\CurrentVersion\Internet Settings, ProxyEnable ; Detect wheter proxy is used or not.
If (proxyEnable)
RegRead, proxyServer, HKCU, Software\Microsoft\Windows\CurrentVersion\Internet Settings, ProxyServer ; Detect address of proxy.
imgPath .= imgName "." imgExtension
pToken := Gdip_Startup()
If (%0%) ; Usually %0% contains the number of command line parameters, but when the user drag'n'drops files onto the script - each of the dropped file gets sent to script as a separate command line parameter, so %0% contains the number of dropped files.
{
Loop, %0%
targetToUpload.Insert({"path": %A_Index%, "dnd": 1})
upload(targetToUpload)
}
If (isThereAnotherInstance())
ExitApp
Return
$Esc:: ; Escape hotkey is used in this script to cancel screenshot area selection. This hotkey is temporary and is enabled only during the periods when the screenshot area selection is active (when red border follows the cursor), the rest of the time this hotkey is disabled in order not to cause any issues with the "Escape" key's work in other programs.
Hotkey, $Esc,, Off
DllCall("gdiplus\GdipDisposeImage", ptr, pBitmap)
firstHit_EventFired := ""
Gui, 1: Destroy
Return
PrintScreen:: ; Since we use the same hotkey trice, we have to distinguish the calls.
Thread, Priority, 1
KeyWait, %A_ThisHotkey%
If !(firstHit_EventFired) ; The user hit PrintScreen - this is a first step.
{
Hotkey, $Esc,, On
SysGet, x0, 76
SysGet, y0, 77
SysGet, w0, 78
SysGet, h0, 79
firstHit_EventFired := 1
MouseGetPos, x1, y1
Gui, 1: -Caption +E0x80000 +HWNDhwnd1 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs ; Create a GUI to use it as a canvas for GDI+ drawing.
Gui, 1: Show, NA
Loop
{
; Draw a rectangular following the cursor.
MouseGetPos, x2, y2
hbm := CreateDIBSection(w0, h0)
hdc := DllCall("CreateCompatibleDC", ptr, 0)
obm := DllCall("SelectObject", ptr, hdc, ptr, hbm)
DllCall("gdiplus\GdipCreateFromHDC", ptr, hdc, ptr "*", G)
DllCall("gdiplus\GdipSetSmoothingMode", ptr, G, "Int", 4)
DllCall("gdiplus\GdipCreatePen1", "UInt", 0xffff0000, "Float", 1, "Int", 2, ptr "*", pPen)
Gdip_DrawLines(G, pPen, x1 - x0 "," y1 - y0 "|" x2 - x0 "," y1 - y0 "|" x2 - x0 "," y2 - y0 "|" x1 - x0 "," y2 - y0 "|" x1 - x0 "," y1 - y0)
DllCall("gdiplus\GdipDeleteBrush", ptr, pPen)
UpdateLayeredWindow(hwnd1, hdc, x0, y0, w0, h0)
DllCall("SelectObject", ptr, hdc, ptr, obm)
DllCall("DeleteObject", ptr, hbm)
DllCall("DeleteDC", ptr, hdc)
DllCall("gdiplus\GdipDeleteGraphics", ptr, G)
Sleep, 20 ; This pause is used to redraw the rectangular less frequently in order to consume less CPU resources. You may adjust the value (it's in miliseconds).
If GetKeyState("Escape", "P") ; User decided to abort screenshooting.
{
GoSub, $Esc ; Abort drawing, unregister "Escape" hotkey.
Break
}
; Second step: user finished selecting the area to screenshoot.
If (GetKeyState("LButton", "P"))
Break
If (GetKeyState(A_ThisHotkey, "P"))
{
KeyWait, %A_ThisHotkey% ; In order to get away from possible issues - let's wait until the PrintScreen key is unpressed.
Break
}
}
Return
}
Else ; User has to hit PrintScreen once again (for the 3rd time) to take a screenshot. I inteionally made not 2, but 3 steps required to take a screenshot: so you can take a screenshot of some event happening, for example, only when you hover something special.
{
Hotkey, $Esc,, Off
firstHit_EventFired := ""
Gui, 1: Destroy ; Hide the rectangular before screenshotting the area
; Save a screenshot to a file.
pBitmap := Gdip_BitmapFromScreen((x1 < x2 ? x1 : x2) "|" (y1 < y2 ? y1 : y2) "|" (x1 < x2 ? x2 - x1 + 1 : x1 - x2 + 1) "|" (y1 < y2 ? y2 - y1 + 1 : y1 - y2 + 1))
Gdip_SaveBitmapToFile(pBitmap, imgPath, jpgQuality)
While !(FileExist(imgPath)) ; Wait until the file gets actually created (otherwise the script will execute the next part too fast).
Sleep, 25
DllCall("gdiplus\GdipDisposeImage", ptr, pBitmap) ; Clean after self.
If (optimizePNG) ; Run png optimizator if user chose to do so.
IfExist, %optipngPath% ; Run it only if it exists.
RunWait, %optipngPath% -o%optimizePNG% -i0 -nc -nb -q -clobber %imgPath%,, Hide
Else
TrayTip, Error, Optipng not found`, thus can't optimize the image.
targetToUpload := []
targetToUpload.Insert({"path": imgPath})
upload(targetToUpload)
If (upload(targetToUpload))
TrayTip, Complete, The image has been successfully uploaded:`n%imgURLs%, 1, 1
}
Return
Exit:
DllCall("gdiplus\GdiplusShutdown", ptr, pToken)
If (hModule := DllCall("GetModuleHandle", "Str", "gdiplus", ptr))
DllCall("FreeLibrary", ptr, hModule)
ExitApp
upload(input) ; Thanks to: maestrith http://www.autohotkey.com/board/user/910-maestrith/ and GeekDude https://github.com/G33kDude
{ ; Upload to Imgur using it's API.
Critical, On
imgURLs := [], filtered := uploadProgress := trueIndex := 0
httpObj := Object()
Gui, -Caption +Border +AlwaysOnTop +ToolWindow
; Gui, ProgressBar: Color, EEAA99
Gui, +LastFound
; WinSet, TransColor, EEAA99
Gui, Add, Text, x0 y0, Uploading image(s)
Gui, Add, Progress, w300 h10 cGreen -0x1 vuploadProgress
Gui, Show, % "x" A_ScreenWidth - 300 " y" A_ScreenHeight -35, Image upload progress
img := ComObjCreate("WIA.ImageFile")
For k, v In input
{
FileGetSize, fileSize, % v.path
If (ErrorLevel)
{
MsgBox, % "There was a problem accessing that file:`n" v.path "`nErrorLevel: " Errorlevel
filtered++
Continue
}
Else If (filesize >= 10485760)
{
MsgBox, % "Skipping file " v.path " that is " filesize/1048576 "Mb, which is beyond Imgur's 10Mb limit for one file."
filtered++
Continue
}
Try img.LoadFile(v.path)
Catch, e
{
MsgBox, % "This was an invalid image or not an image file at all.`nFile: " v.path "`nError: " e "`nError message: " e.Message "`nError what: " e.What "`nError extra: " e.Extra "`nError file: " e.File "`nError line: " e.Line
filtered++
Continue
}
; ip := ComObjCreate("WIA.ImageProcess")
; ip.filters.add(IP.FilterInfos("Convert").FilterID)
; ip.filters(1).properties("FormatID").value := "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}" ; = png, {B96B3CAE-0728-11D3-9D7B-0000F81EF32E} = jpg
; ip.filters(1).properties("Quality").value := 100
; img := ip.apply(img)
data := img.FileData.BinaryData
httpObj[++trueIndex] := ComObjCreate("WinHttp.WinHttpRequest.5.1")
httpObj[trueIndex].Open("POST", "https://api.imgur.com/3/upload")
If (proxyEnable)
; {
httpObj[trueIndex].SetProxy(2, proxyServer)
; httpObj[trueIndex].SetCredentials(proxyUser, proxyPass, 1) ; HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1
; }
httpObj[trueIndex].SetRequestHeader("Authorization", "Client-ID " imgurClientID)
httpObj[trueIndex].SetRequestHeader("Content-Length", size)
Try
{
GuiControl,, uploadProgress, % Round(A_Index * 50 / input.MaxIndex() - filtered)
Errorlevel := 0
httpObj[trueIndex].Send(data)
}
Catch, e
{
filtered++
MsgBox, % "Please, try again, because the script failed to upload your screenshot """ v.path """ due to a server-issue:`n" e "`nError message: " e.Message "`nError what: " e.What "`nError extra: " e.Extra "`nError file: " e.File "`nError line: " e.Line
}
If (tempScreenshot && !v.dnd) ; User specified to delete the local screenshot's file after uploading it.
FileDelete, % v.path
}
filtered := trueIndex := 0
While (httpObj.Length())
{
trueIndex := (++trueIndex > httpObj.Length() ? trueIndex - httpObj.Length() : trueIndex++)
If (InStr(httpObj[trueIndex].ResponseText, "status"":200", -1) && (RegExMatch(httpObj[trueIndex].ResponseText, "i)""link"":""http:\\/\\/(.*?(jpg|jpeg|png|gif|apng|tiff|tif|bmp|pdf|xcf))""", Match)))
{
httpObj.RemoveAt(trueIndex--)
imgURLs.Push("https://" RegExReplace(Match1, "\\/", "/"))
GuiControl,, uploadProgress, % Round(50 + (++filtered * 50 / httpObj.Length()))
}
Else
MsgBox, % "The server returned an error:`n" httpObj[k].ResponseText
}
For k, v in imgURLs
If (clipURL != 1)
Run, % v
If (clipURL)
Clipboard := arr2ASV(imgURLs)
Gui, Destroy
Critical, Off
}
arr2ASV(arr, separator := " ") ; Parses the input array and outputs it's values as a string with anchor-separated values.
{
For k, v In arr
var ? var .= separator v : var := v
Return var
}
isThereAnotherInstance() ; Thanks to: GeekDude http://www.autohotkey.com/board/user/10132-geekdude/
{
DetectHiddenWindows, On
WinGet, wins, List, ahk_class AutoHotkey
Loop, %wins%
{
WinGetTitle, win, % "ahk_id " wins%A_Index%
If (RegExReplace(win, "^(.*) - AutoHotkey v[0-9\.]+$", "$1") == A_ScriptFullPath)
{
WinGet, wpid, PID, % "ahk_id " wins%A_Index%
If (wpid != DllCall("GetCurrentProcessId"))
Return wpid
}
}
DetectHiddenWindows, Off
Return 0
}
;{ GDI+ functions
Gdip_Startup()
{
If !(DllCall("GetModuleHandle", "Str", "gdiplus", ptr))
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", ptr "*", pToken, ptr, &si, ptr, 0)
Return pToken
}
CreateDIBSection(w, h, hdc = "")
{
hdc2 := hdc ? hdc : DllCall("GetDC", ptr, 0)
VarSetCapacity(bi, 40, 0)
NumPut(w, bi, 4, "UInt"), NumPut(h, bi, 8, "UInt"), NumPut(40, bi, 0, "UInt"), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "UInt"), NumPut(32, bi, 14, "ushort")
hbm := DllCall("CreateDIBSection", ptr, hdc2, ptr, &bi, "UInt", 0, ptr "*", 0, Ptr, 0, "UInt", 0, ptr)
If !(hdc)
DllCall("ReleaseDC", ptr, 0, ptr, hdc2)
Return hbm
}
Gdip_DrawLines(pGraphics, pPen, Points)
{
StringSplit, Points, Points, |
VarSetCapacity(PointF, 8 * Points0)
Loop, % Points0
{
StringSplit, Coord, Points%A_Index%, `,
NumPut(Coord1, PointF, 8 * (A_Index - 1), "Float"), NumPut(Coord2, PointF, (8 * (A_Index - 1)) + 4, "Float")
}
Return DllCall("gdiplus\GdipDrawLines", ptr, pGraphics, ptr, pPen, ptr, &PointF, "Int", Points0)
}
UpdateLayeredWindow(hwnd, hdc, x = "", y = "", w = "", h = "", Alpha = 255)
{
If ((x != "") && (y != ""))
VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
If ((w = "") || (h = ""))
WinGetPos,,, w, h, ahk_id %hwnd%
Return DllCall("UpdateLayeredWindow", ptr, hwnd, ptr, 0, ptr, ((x = "") && (y = "")) ? 0 : &pt, "Int64*", w | h << 32, ptr, hdc, "Int64*", 0, "UInt", 0, "UInt*", Alpha << 16 | 1 << 24, "UInt", 2)
}
Gdip_BitmapFromScreen(screen)
{
If (SubStr(screen, 1, 5) = "hwnd:")
{
screen := SubStr(screen, 6)
If !(WinExist("ahk_id " screen))
Return -2
WinGetPos,,, w, h, ahk_id %screen%
x := y := 0
hhdc := DllCall("GetDCEx", ptr, screen, ptr, 0, "Int", 3)
}
Else If (screen&1 != "")
{
Sysget, M, Monitor, %screen%
x := MLeft, y := MTop, w := MRight - MLeft, h := MBottom - MTop
}
Else
{
StringSplit, S, screen, |
x := S1, y := S2, w := S3, h := S4
}
If ((x = "") || (y = "") || (w = "") || (h = ""))
Return -1
chdc := DllCall("CreateCompatibleDC", ptr, 0), hbm := CreateDIBSection(w, h, chdc), obm := DllCall("SelectObject", ptr, chdc, ptr, hbm), hhdc := hhdc ? hhdc : DllCall("GetDC", ptr, 0)
DllCall("gdi32\BitBlt", ptr, chdc, "Int", 0, "Int", 0, "Int", w, "Int", h, ptr, hhdc, "Int", x, "Int", y, "UInt", 0x00CC0020)
DllCall("ReleaseDC", ptr, 0, ptr, hhdc)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", ptr, hbm, ptr, 0, ptr "*", pBitmap)
DllCall("SelectObject", ptr, chdc, Ptr, obm), DllCall("DeleteObject", ptr, hbm), DllCall("DeleteDC", ptr, hhdc), DllCall("DeleteDC", ptr, chdc)
Return pBitmap
}
Gdip_SaveBitmapToFile(pBitmap, sOutput, quality = 100)
{
SplitPath, sOutput,,, Extension
If Extension Not In BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
Return -1
DllCall("gdiplus\GdipGetImageEncodersSize", "UInt*", nCount, "UInt*", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, ptr, &ci)
If !(nCount && nSize)
Return -2
If (A_IsUnicode)
{
StrGet_Name := "StrGet"
Loop, % nCount
{
sString := %StrGet_Name%(NumGet(ci, (idx := (48 + 7 * A_PtrSize) * (A_Index - 1)) + 32 + 3 * A_PtrSize), "UTF-16")
If !(InStr(sString, "*." Extension))
Continue
pCodec := &ci + idx
Break
}
}
Else
{
Loop, % nCount
{
Location := NumGet(ci, 76 * (A_Index - 1) + 44)
nSize := DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", Location, "Int", -1, "UInt", 0, "Int", 0, "UInt", 0, "UInt", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", Location, "Int", -1, "Str", sString, "Int", nSize, "UInt", 0, "UInt", 0)
If !(InStr(sString, "*." Extension))
Continue
pCodec := &ci + 76 * (A_Index - 1)
Break
}
}
If !(pCodec)
Return -3
If Extension in JPG,JPEG,JPE,JFIF
{
quality := (quality < 0) ? 0 : ((quality > 100) ? 100 : quality)
DllCall("gdiplus\GdipGetEncoderParameterListSize", ptr, pBitmap, ptr, pCodec, "UInt*", nSize)
VarSetCapacity(EncoderParameters, nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", ptr, pBitmap, ptr, pCodec, "UInt", nSize, ptr, &EncoderParameters)
Loop, % NumGet(EncoderParameters, "UInt")
{
elem := (24 + (A_PtrSize ? A_PtrSize : 4)) * (A_Index - 1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
If ((NumGet(EncoderParameters, elem +1 6, "UInt") = 1) && (NumGet(EncoderParameters, elem + 20, "UInt") = 6))
{
p := elem + &EncoderParameters - pad - 4
NumPut(quality, NumGet(NumPut(4, NumPut(1, p + 0) + 20, "UInt")), "UInt")
Break
}
}
}
If !(A_IsUnicode)
{
nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, ptr, &sOutput, "Int", -1, ptr, 0, "Int", 0)
VarSetCapacity(wOutput, nSize * 2)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, ptr, &sOutput, "Int", -1, ptr, &wOutput, "Int", nSize)
VarSetCapacity(wOutput, -1)
If !(VarSetCapacity(wOutput))
Return -4
E := DllCall("gdiplus\GdipSaveImageToFile", ptr, pBitmap, ptr, &wOutput, ptr, pCodec, "UInt", p ? p : 0)
}
Else
E := DllCall("gdiplus\GdipSaveImageToFile", ptr, pBitmap, ptr, &sOutput, ptr, pCodec, "UInt", p ? p : 0)
Return E ? -5 : 0
}
;}