-
Notifications
You must be signed in to change notification settings - Fork 69
/
Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.ahk
102 lines (81 loc) · 3.45 KB
/
Gdip.Tutorial.12-Pixelate.a.bitmap.using.machine.code.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
; gdi+ ahk tutorial 12 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to pixelate a bitmap using machine code
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk
; Start gdi+
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
; Create a layered window that is always on top as usual and get a handle to the window
Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 1: Show, NA
hwnd1 := WinExist()
; If the image we want to work with does not exist on disk, then download it...
If !FileExist("MJ.jpg")
UrlDownloadToFile, http://www.autohotkey.net/~tic/MJ.jpg, MJ.jpg
; Get a bitmap from the image
pBitmap := Gdip_CreateBitmapFromFile("MJ.jpg")
;pBitmap := Gdip_BitmapFromScreen()
If !pBitmap
{
MsgBox, 48, File loading error!, Could not load the image specified
ExitApp
}
; Get the width and height of the bitmap we have just created from the file
Width := Gdip_GetImageWidth(pBitmap), Height := Gdip_GetImageHeight(pBitmap)
; We also need to create
pBitmapOut := Gdip_CreateBitmap(Width, Height)
; As normal create a gdi bitmap and get the graphics for it to draw into
hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
; Call WM_LBUTTONDOWN every time the gui is clicked, to allow it to be dragged
OnMessage(0x201, "WM_LBUTTONDOWN")
; Update the window with the hdc so that it has a position and dimension for future calls to not
; have to explicitly pass them
UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)
; Set a timer to update the gui with our pixelated bitmap
SetTimer, Update, 50
return
;#######################################################################
Update:
; Some simple checks to see if we are increasing or decreasing the pixelation
; v is the block size of the pixelation and dir is the direction (inc/decreasing)
if (v <= 1)
v := 1, dir := !dir
else if (v >= 30)
v := 30, dir := !dir
; Call Gdip_PixelateBitmap with the bitmap we retrieved earlier and the block size of the pixels
; The function returns the pixelated bitmap, and doesn't dispose of the original bitmap
Gdip_PixelateBitmap(pBitmap, pBitmapOut, dir ? ++v : --v)
; We can optionally clear the graphics we will be drawing to, but if we know there will be no transparencies then
; it doesn't matter
;Gdip_GraphicsClear(G)
; We then draw our pixelated bitmap into our graphics and dispose of the pixelated bitmap
Gdip_DrawImage(G, pBitmapOut, 0, 0, Width, Height, 0, 0, Width, Height)
; We can now update our window, and don't need to provide a position or dimensions as we don't want them to change
UpdateLayeredWindow(hwnd1, hdc)
return
;#######################################################################
; This is called on left click to allow to drag
WM_LBUTTONDOWN()
{
PostMessage, 0xA1, 2
}
;#######################################################################
; On exit, dispose of everything created
Esc::
Exit:
Gdip_DisposeImage(pBitmapOut), Gdip_DisposeImage(pBitmap)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)
ExitApp
return