graphics: create icons from scratch

Post your working scripts, libraries and tools
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

graphics: create icons from scratch

11 Aug 2017, 22:13

Two example scripts, both create an icon file and save it to disk and set the active window icon. One creates an icon with a lowercase i, the other creates a one-colour icon.

Code: Select all

;icon data from:
;Crazy Scripting : Include an Icon in your script - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/31044-crazy-scripting-include-an-icon-in-your-script/#entry185642

q:: ;create icon file / set active window icon
;ICONDIR 1 of 2 (6 bytes):
vDataHex := "000001000100"
;ICONDIR 2 of 2: ICONDIRENTRY (16 bytes):
vDataHex .= "10101000010004002801000016000000"
;ICONIMAGE 1 of 4: BITMAPINFOHEADER (40 bytes):
vDataHex .= "2800000010000000200000000100040000000000C000000000000000000000000000000000000000"
;ICONIMAGE 2 of 4: colour table (16 colours) (64 bytes):
vDataHex .= "C6080800CE101000CE181800D6212100D6292900E13F3F00E7525200EF5A5A00EF636300F76B6B00F7737300FF7B7B00FFC6C600FFCEC600FFDEDE00FFFFFF00"
;ICONIMAGE 3 of 4: pixels (colour mask) (XOR mask) (128 bytes):
vDataHex .= "CCCCCCCCCCCCCCCCC00000000000000CC11111111111111CC22222CFFE22222CC33333CFFE33333CC44444CFFE44444CC55555CFFE55555CC55555CFFE55555CC55555CFFE55555CC66666CFFE66666CC77777777777777CC88888CFFC88888CC99999CFFC99999CCAAAAAAAAAAAAAACCBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCC"
;ICONIMAGE 4 of 4: pixels (opacity mask) (AND mask) (64 bytes):
vDataHex .= "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

vSize := StrLen(vDataHex)//2
VarSetCapacity(vData, vSize)
Loop, % vSize
	NumPut("0x" SubStr(vDataHex,2*A_Index-1,2), vData, A_Index-1, "UChar")

;set active window icon:
WinGet, hWnd, ID, A
hIcon := DllCall("user32\CreateIconFromResourceEx", Ptr,&vData+22, UInt,NumGet(vData,14,"UInt"), Int,1, UInt,0x30000, Int,16, Int,16, UInt,0)
SendMessage, 0x80, 0, % hIcon,, % "ahk_id " hWnd ;WM_SETICON := 0x80 ;sets title bar icon + taskbar icon
SendMessage, 0x80, 1, % hIcon,, % "ahk_id " hWnd ;WM_SETICON := 0x80 ;sets alt+tab icon

;create icon file:
vPath = %A_Desktop%\z ico %A_Now%.ico
if FileExist(vPath)
	return
oFile := FileOpen(vPath, "w")
oFile.RawWrite(vData, vSize)
oFile.Close()
Run, % vPath
return

;==================================================

w:: ;create icon file (one colour) / set active window icon
vColRGB := "FF0000" ;red
;vColRGB := "FFFF00" ;yellow
;vColRGB := "00FF00" ;lime
;vColRGB := "0000FF" ;blue
vCol := SubStr(vColRGB,5,2) SubStr(vColRGB,3,2) SubStr(vColRGB,1,2) "00"

;ICONDIR 1 of 2 (6 bytes):
vDataHex := "000001000100"
;ICONDIR 2 of 2: ICONDIRENTRY (16 bytes):
vDataHex .= "10101000010004002801000016000000"
;ICONIMAGE 1 of 4: BITMAPINFOHEADER (40 bytes):
vDataHex .= "2800000010000000200000000100040000000000C000000000000000000000000000000000000000"
;ICONIMAGE 2 of 4: colour table (16 colours) (64 bytes):
vDataHex .= vCol ;(remaining bytes are 0)
;ICONIMAGE 3 of 4: pixels (colour mask) (XOR mask) (128 bytes):
;(all bytes are 0)
;ICONIMAGE 4 of 4: pixels (opacity mask) (AND mask) (64 bytes):
;(all bytes are 0)

vSize := 318
VarSetCapacity(vData, vSize)
Loop, % vSize
	NumPut("0x" SubStr(vDataHex,2*A_Index-1,2), vData, A_Index-1, "UChar")

;set active window icon:
WinGet, hWnd, ID, A
hIcon := DllCall("user32\CreateIconFromResourceEx", Ptr,&vData+22, UInt,NumGet(vData,14,"UInt"), Int,1, UInt,0x30000, Int,16, Int,16, UInt,0)
SendMessage, 0x80, 0, % hIcon,, % "ahk_id " hWnd ;WM_SETICON := 0x80 ;sets title bar icon + taskbar icon
SendMessage, 0x80, 1, % hIcon,, % "ahk_id " hWnd ;WM_SETICON := 0x80 ;sets alt+tab icon

;create icon file:
vPath = %A_Desktop%\z ico %A_Now%.ico
if FileExist(vPath)
	return
oFile := FileOpen(vPath, "w")
oFile.RawWrite(vData, vSize)
oFile.Close()
Run, % vPath
return
==================================================

NOTES: HEIGHT MULTIPLIED BY 2

Icons
https://msdn.microsoft.com/en-us/library/ms997538.aspx
The biHeight member specifies the combined height of the XOR and AND masks.
So for a 16x16 icon, a biHeight of 32 should be specified.

==================================================

NOTES: PADDING IN THE AND MASK

Icons
https://msdn.microsoft.com/en-us/library/ms997538.aspx
The number of bytes in this array is determined by examining the icHeader member, and assuming 1bpp. The dimensions of this bitmap must be the same as the dimensions of the XOR mask.
So for a 16x16 icon, the XOR mask should be 16*16*(1/8) = 32 bytes in size, + padding (explained below), giving 64 bytes.

==================================================

NOTES: ICONIMAGE STRUCT

In the example script for a 16x16 icon, the ICONIMAGE struct contains a BITMAPINFOHEADER, a lookup table with 16 RGB values for 16 colours, the XOR mask with values corresponding to the lookup table, the AND mask with values relating to transparency.

The sizes for each of those four parts is as follows:
- BITMAPINFOHEADER (40 bytes)
- colour table (16*4 bytes = 64 bytes)
- pixels (colour mask) (XOR mask) (16*16*(1/2) = 128 bytes) (each pixel is represented by 4 bits, i.e. half a byte)
- pixels (opacity mask) (AND mask) (16*16*(1/8) + 32 = 64 bytes) (each pixel needs 1 bit, so each row of 16 pixels takes up 2 bytes, but each row of pixels must start at a 4-byte offset, and so 2 bytes of padding are needed for each row of pixels, and thus 4 bytes per of row, and 16 rows in total gives: 4*16=64 bytes)

==================================================

LINKS:

Crazy Scripting : Include an Icon in your script - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/3104 ... ntry185642
[ICONDIRENTRY struct]
Icons
https://msdn.microsoft.com/en-us/library/ms997538.aspx
BITMAPINFOHEADER structure (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
ICO (file format) - Wikipedia
https://en.wikipedia.org/wiki/ICO_(file_format)
graphics: create bmp files from scratch - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=34952
Reading AND mask of 16x16 images from ICO file in Lua - Stack Overflow
https://stackoverflow.com/questions/345 ... ile-in-lua

FURTHER LINKS:
The .ICO file and it`s struct ?
https://social.msdn.microsoft.com/Forum ... =vcgeneral
The format of icon resources – The Old New Thing
https://blogs.msdn.microsoft.com/oldnew ... 00/?p=7083
The evolution of the ICO file format, part 1: Monochrome beginnings – The Old New Thing
https://blogs.msdn.microsoft.com/oldnew ... 0/?p=12513
Replacing ICON resources in EXE and DLL files - CodeProject
https://www.codeproject.com/Articles/30 ... -DLL-files
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 25 guests