Foreword
When i was working on including files into an uncompiled script I had this little side project and i am pretty proud of it.
It is a function that can create a bitmap from a list of colors (in BGR) and a specified width and height.
Application
WriteBMP(file ; the file to save the bitmap to ,colors ; the list of colors [color=red]IN BGR FORMAT!!![/color] for ex. "102bacf810ace01..." ,width ; width of the bitmap (default = 16) ,height ; height of the bitmap (default = 16) ,padded) ; if the bitmap is padded pass a 1 (if you dont know what that means, pass 0 or leave blank)
It comes in handy for taking snapshots of a portion of the screen, rather than screen printing then editing in paing. Aside from the fact that bitmaps are relatively huge in file size it is really useful.WriteBMP(file,colors,width=16,height=16,padded=0) { ;first check if we have the right number of pixels if padded = 0 if strlen(colors)/6 <> height*width msgbox,% "Pixel Mismatch detected!`n(The Height*Width you specified does not match the number of pixels you provided, or the padding is incorrect) The BMP will be corrupted.`nWidth:" width " Height:" Height "`nPixels provided:" strlen(colors)/6 " Pixels needed: " width*height if padded if (strlen(colors)/6 - mod(width,4)*height)<> height*width msgbox,% "Pixel Mismatch detected!`n(The Height*Width you specified does not match the number of pixels you provided, or the padding is incorrect) The BMP will be corrupted.`nWidth:" width " Height:" Height "`nPixels provided:" strlen(colors)/6 " Pixels needed: " width*height ;if the bitmap is not padded we need to pad it if (padded = 0) and (mod(width,4) <> 0) ;our bitmap was not provided with padding and it needs it { loop, %height% { stringmid,row,colors,% width * 6 * (A_index-1) + 1,% width*6 colorspadded := colorspadded row removehex(padhex(0,mod(width,4))) ;add the needed number of 00 bytes } colors := colorspadded } ;now we need to create the actual bitmap, starting with the header setformat,integer,H width := removehex(padhex(width+0,4)) ;this makes the width and height into "words" or 4 bytes long height := removehex(padhex(height+0,4)) ; B M size reserved offbits bitsize planes bitcount (24 bit), and the rest is color table (0s) BMPHex := "424d0000000000000000" . "3600000028000000" . width . height "0100" . "1800" . "000000000000000000000000000000000000000000000000" . colors ;Create the file Handle := DllCall("CreateFile","str",file,"Uint",0x40000000 ,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0) Loop { if strlen(BMPHex) = 0 break StringLeft, Hex, BMPHex, 2 StringTrimLeft, BMPHex, BMPHex, 2 Hex = 0x%Hex% DllCall("WriteFile","UInt", Handle,"UChar *", Hex ,"UInt",1,"UInt *",UnusedVariable,"UInt",0) } ;close the file DllCall("CloseHandle", "Uint", Handle) return 0 } padhex(hexin,bytes) ;pads a hex number to the specified byte length { if Mod(strlen(hexin),2) ;the string is an odd number of digits long { hexin := removehex(hexin) ; remove the "0x" temporarily hexin := "0x0" hexin ;for ex: A into 0x0A ; now add "0x0" } loop, % bytes - strlen(hexin)/2 + 1 ;add zeros to the end till we get the desired byte length hexin := hexin "00" return hexin } removehex(hexin) ;removes the 0x from hex { stringleft,beg,hexin,2 if beg = 0x stringtrimleft,hexin,hexin,2 return hexin }
Example
If you Ctrl-Drag on the screen it takes a snapshot of that section of the screen and saves it to your desktop (i hope). I created this because i was tired of having to printscreen my whole 1600*1200 desktop and then edit the file for a 16*16 picture. Please post feedback!#singleinstance force #noenv file = C:\Documents and Settings\%A_username%\Desktop\ThisBMPwasmadewithAHK.bmp ~^LButton:: colorlist = CoordMode, Mouse, Screen CoordMode, Tooltip, Screen CoordMode, Pixel, Screen MouseGetPos, start_x, start_y ToolTip, ., start_x, start_y WinSet, Transparent, 100, ahk_class tooltips_class32 loop { MouseGetPos, current_x, current_y WinMove, ahk_class tooltips_class32, , , , % current_x - start_x, % current_y - start_y GetKeyState, state, LButton if state=u { tooltip break } } mousegetpos, end_x, end_y TrayTip, ,Retreiving Colors..., , 1 width := end_x - start_x height := end_y - start_y loop, %height% { pixely := start_y + height - A_index - 1 ;because bitmaps are written backwards loop, %width% { pixelx := start_x + A_index - 1 pixelgetcolor,color,pixelx,pixely ;get the BGR value color := removehex(color) colorlist := colorlist color } } TrayTip, ,Saving Bitmap..., , 1 WriteBMP(file,colorlist,width,height,0) TrayTip, ,Done!, , 1 return WriteBMP(file,colors,width=16,height=16,padded=0) { ;first check if we have the right number of pixels if padded = 0 if strlen(colors)/6 <> height*width msgbox,% "Pixel Mismatch detected!`n(The Height*Width you specified does not match the number of pixels you provided, or the padding is incorrect) The BMP will be corrupted.`nWidth:" width " Height:" Height "`nPixels provided:" strlen(colors)/6 " Pixels needed: " width*height if padded if (strlen(colors)/6 - mod(width,4)*height)<> height*width msgbox,% "Pixel Mismatch detected!`n(The Height*Width you specified does not match the number of pixels you provided, or the padding is incorrect) The BMP will be corrupted.`nWidth:" width " Height:" Height "`nPixels provided:" strlen(colors)/6 " Pixels needed: " width*height ;if the bitmap is not padded we need to pad it if (padded = 0) and (mod(width,4) <> 0) ;our bitmap was not provided with padding and it needs it { loop, %height% { stringmid,row,colors,% width * 6 * (A_index-1) + 1,% width*6 colorspadded := colorspadded row removehex(padhex(0,mod(width,4))) ;add the needed number of 00 bytes } colors := colorspadded } ;now we need to create the actual bitmap, starting with the header setformat,integer,H width := removehex(padhex(width+0,4)) ;this makes the width and height into "words" or 4 bytes long height := removehex(padhex(height+0,4)) ; B M size reserved offbits bitsize planes bitcount (24 bit), and the rest is color table (0s) BMPHex := "424d0000000000000000" . "3600000028000000" . width . height "0100" . "1800" . "000000000000000000000000000000000000000000000000" . colors ;Create the file Handle := DllCall("CreateFile","str",file,"Uint",0x40000000 ,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0) Loop { if strlen(BMPHex) = 0 break StringLeft, Hex, BMPHex, 2 StringTrimLeft, BMPHex, BMPHex, 2 Hex = 0x%Hex% DllCall("WriteFile","UInt", Handle,"UChar *", Hex ,"UInt",1,"UInt *",UnusedVariable,"UInt",0) } ;close the file DllCall("CloseHandle", "Uint", Handle) return 0 } padhex(hexin,bytes) ;pads a hex number to the specified byte length { if Mod(strlen(hexin),2) ;the string is an odd number of digits long { hexin := removehex(hexin) ; remove the "0x" temporarily hexin := "0x0" hexin ;for ex: A into 0x0A ; now add "0x0" } loop, % bytes - strlen(hexin)/2 + 1 ;add zeros to the end till we get the desired byte length hexin := hexin "00" return hexin } removehex(hexin) ;removes the 0x from hex { stringleft,beg,hexin,2 if beg = 0x stringtrimleft,hexin,hexin,2 return hexin }
Special thanks to Goyyah for his great idea for organizing a post using qoutes