AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Make an ICON (.ico)

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
apocalypse~r



Joined: 21 Jun 2007
Posts: 24

PostPosted: Mon Jun 02, 2008 1:57 am    Post subject: Make an ICON (.ico) Reply with quote

Just include these files in a script:
a_functions:
Code:

numbasechng(number, base, endbase = 10)
{
  numfrmt = %a_formatfloat%
  if (base > 64)
  {
    setformat, float, %numfrmt%
    errorlevel = -2
    return
  }
  else if base = 16
    stringreplace, number, number, 0x,
  if (endbase > 64)
  {
    setformat, float, %numfrmt%
    errorlevel = -3
    return
  }
  if number = 0
    return, 0
  setformat, float, 0.15
  stringcasesense, on
  errorlevel = 0
  if base is not integer
  {
    setformat, float, %numfrmt%
    errorlevel = 2
    return
  }
  if endbase is not integer
  {
    setformat, float, %numfrmt%
    errorlevel = 3
    return
  }
  ifinstring, number, -
  {
    neg = -
    stringreplace, number, number, -, , A
  }
  total = 0
  ifinstring, number, .
  {
    dedec := instr(number, ".", 0, 1)
    decimal := substr(number, dedec)
    decimalb10 := 0
    number := substr(number, 1, dedec - 1)
    decimalvalue = .
    loop, parse, decimal
    {
      if a_index = 1
        continue
      char := a_loopfield
      gosub, swapout
      decimalb10 := decimalb10 + (char * (base ** -(a_index - 1)))
    }
    if endbase <> 10
    {
      loop
      {
        char := floor(.00000000000001 + decimalb10 / (1 / ((endbase ** a_index))))
        decimalb10 := decimalb10 - (char * (1 / ((endbase ** a_index))))
        gosub, unswap
        decimalvalue = %decimalvalue%%char%
        if a_index > 10
          break
      }
    }
    else
      decimalvalue := decimalb10
  loop, parse, decimalvalue, %a_space%, 0
    decimalvalue := a_loopfield
  }
  length := strlen(number)
  loop, parse, number,
  {
    char := a_loopfield
    gosub, swapout
    total := total + char * (base ** (length - a_index))
  }
  setformat, float, %numfrmt%
  if endbase = 10
  {
    if not decimal
      return, neg . total
    else
      return, neg . total . decimalvalue
  }
  newlength := ceil(log(floor(total) + 1) / log(endbase))
  loop, %newlength%
  {
    char := floor(total / (endbase ** (newlength - a_index)))
    total := total - char * endbase ** (newlength - a_index)
    gosub, unswap
    endnumber := endnumber . char
  }
  if not decimal
    return, neg . endnumber
  else
    return, neg . endnumber decimalvalue
  return

  swapout:
  if char between a and z
    char := asc(char) - 87
  if char between A and Z
    char := asc(char) - 29
  if char = /
    char := 62
  if char = *
    char := 63
  return

  unswap:
  if char between 10 and 35
    char := chr(char + 87)
  if char between 36 and 61
    char := chr(char + 29)
  if char = 62
    char = /
  if char = 63
    char = *
  return
}
readfiletovar(_filename, byref _data, _byteNB = 0, _MoveMethod = -1, _offset = 0)
{
  global
;  local handle, granted, result, read, filesize
  handle := Dllcall("CreateFile", "Str", _filename, "UInt", 0x80000000, "UInt", 3, "UInt", 0, "UInt", 3, "UInt", 0, "UInt", 0)
  if (handle = INVALID_HANDLE_VALUE or handle = 0)
  {
    errorlevel = -1
    return, -1
  }
  if (_moveMethod != -1)
  {
    _offset := DllCall("SetFilePointer", "UInt", handle, "Int", _offset, "UInt", 0, "UInt", _moveMethod)
    if (_offset = -1)
    {
      ErrorLevel = -2
      dllcall("CloseHandle", "UInt", handle)
      return -2
    }
  }
  if (_byteNB = 0)
  {
    _byteNB := Dllcall("GetFileSize", "UInt", handle, "UInt", 0)
    if (_byteNB = 0xFFFFFFFF)
    {
      errorlevel = -3
      dllcall("CloseHandle", "UInt", handle)
      return -3
    }
  }
  varsetcapacity(_data, 0, 0)
  granted := varsetcapacity(_data, _byteNB, 0)
  if (granted < _byteNB)
  {
    errorlevel := %granted%
    dllcall("CloseHandle", "UInt", handle)
    return -4
  }
  if (dllcall("ReadFile", "UInt", handle, "Str", _data, "UInt", _byteNb, "UInt *", read, "UInt", 0) = 0)
  {
    errorlevel := -5
    dllcall("CloseHandle", "UInt", handle)
    return -5
  }
  dllcall("CloseHandle", "UInt", handle)
  return read
}
writevartofile(_filename, byref _data, _byteNB = 0, _movemethod = -1, _offset = 0, _overwrite = 0)
{
  if _overwrite / 2 <> floor(_overwrite / 2)
    filedelete, %_filename%
  if (_overwrite >> 1 >= 1)
    filecreatedir, % diroffile(_filename)
  handle := dllcall("CreateFile", "Str", _filename, "UInt", 0x40000000, "UInt", 3, "UInt", 0, "UInt", 4, "UInt", 0, "UInt", 0)
  if (handle = INVALID_HANDLE_VALUE or handle = -1)
  {
    errorlevel := -1
    return, -1
  }
  if (_moveMethod != -1)
  {
    _offset := DllCall("SetFilePointer", "UInt", handle, "Int", _offset, "UInt", 0, "UInt", _moveMethod)
    if (_offset = -1)
    {
      errorLevel = -2
      dllcall("CloseHandle", "UInt", handle)
      return -2
    }
  }
  datasize := varsetcapacity(_data)
  if (_byteNB < 1 or byteNB > datasize)
    _byteNB := datasize
  if (dllcall("WriteFile", "UInt", handle, "Str", _data, "UInt", _byteNb, "UInt *", written, "UInt", 0) = 0 or written < _byteNB)
  {
    errorlevel := -3
    dllcall("CloseHandle", "UInt", handle)
    return -3
  }
  dllcall("CloseHandle", "UInt", handle)
  return written
}

convertbintohex(byref _data, byref _output)
{
  loop
  {
    index := a_index - 1
    loop, 10000
    {
      chr := numget(_data, (a_index - 1) + 10000 * index, "UChar")
      if chr >= 16
        tmp := tmp . numbasechng(chr, 10, 16)
      else if chr =
      {
        break = 1
        break
      }
      else if chr < 16
        tmp := tmp . "0" . numbasechng(chr, 10, 16)
    }
    if break = 1
    {
      stringtrimright, asciibinstr, asciibinstr, 4
      fileappend, %tmp%, %a_temp%\ahkbin.txt
      fileread, _output, %a_temp%\ahkbin.txt
      filedelete, %a_temp%\ahkbin.txt
      return
    }
    guicontrol, , progress, % a_index * size
    fileappend, %tmp%, %a_temp%\ahkbin.txt
    tmp =
  }
}

converthextobin(_data, byref _output)
{
  if strlen(_data) / 2 - 1 = strlen(_data) // 2 - 1
    varsetcapacity(_output, strlen(_data) / 2 - 1)
  else
  {
    errorlevel = 1
    return
  }
  loop % strlen(_data) / 2 - 1
  {
    numput(numbasechng(substr(_data, a_index * 2 - 1, 2), 16, 10), _output, a_index - 1, "uchar")
  }
}

switchendianhexint(in, p = 0)
{
  loop, % 8 - strlen(in)
    in := "0" . in
  if p = 0
  {
    loop, 4
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2)
  }
  else
  {
    loop, 4
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2) . " "
  }
  return, %output%
}

switchendianhexshort(in, p = 0)
{
  loop, % 4 - strlen(in)
    in := "0" . in
  if p = 0
  {
    loop, 2
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2)
  }
  else
  {
    loop, 2
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2) . " "
  }
  return, %output%
}

switchendianhexlong(in, p = 0)
{
  loop, % 16 - strlen(in)
    in := "0" . in
  if p = 0
  {
    loop, 8
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2)
  }
  else
  {
    loop, 8
      output := output . substr(in, strlen(in) - 2 * a_index + 1, 2) . " "
  }
  return, %output%
}

Icon Functions:
Code:

get_starting_offset_icon(n)
{
  return, % 6 + 16 * n
}

makeinternalbitmapheader(w, h, d)
{
  f := 54 + h * ceil(((d / 8) * w) / 4) * 4 + 4 * (2 ** d) * (d < 16)
  bmp_magicnum := "424d"
  bmp_filesize := switchendianhexint(numbasechng(f, 10, 16))
  bmp_reserved := "41484b00"
  bmp_offset := switchendianhexint(numbasechng(54 + 4 * (2 ** d) * (d < 16), 10, 16))
  bmp_header := bmp_magicnum . bmp_filesize . bmp_reserved . bmp_offset
  return %bmp_header%
}

makebitmapheader(w, h, d)
{
  global bmp_filesize
  bmp_hsize := "28 00 00 00 "
  bmp_w := switchendianhexint(numbasechng(w, 10, 16), 1)
  bmp_h := switchendianhexint(numbasechng(h, 10, 16), 1)
  bmp_planes := "01 00 "
  bmp_depth := switchendianhexshort(numbasechng(d, 10, 16), 1)
  bmp_method := "00 00 00 00 "
  bmp_imgsize := switchendianhexint(numbasechng(h * (ceil((d / 8) / 4 * w) * 4), 10, 16), 1)
  bmp_res := switchendianhexlong(0, 1)
  bmp_palette := (d >= 16) ? switchendianhexint(0, 1) : switchendianhexint(numbasechng(2 ** d, 10, 16), 1)
  bmp_important := switchendianhexint(0, 1)
  bmp_filesize := 54 + h * (ceil((d / 8) / 4 * w) * 4) + (4 * (2 ** d) * (d < 16))
  bmp_header := bmp_hsize . bmp_w . bmp_h . bmp_planes . bmp_depth . bmp_method . bmp_imgsize . bmp_res . bmp_palette . bmp_important
  return, %bmp_header%
}

checkbitmap(n)
{
  local rawdata
  readfiletovar(n, rawdata, 6, 0, 0)
  convertbintohex(rawdata, hexdata)
  if (not (substr(hexdata, 1, 4) == "424d"))
    return, 0
  filegetsize, size, %n%
  if (numbasechng(switchendianhexint(substr(hexdata, 5, 8)), 16, 10) <> size)
    return, 0
  return, 1
}

makeiconfrombitmap(dp, n1, t1 = "", n2 = "", t2 = "", n3 = "", t3 = "", n4 = "", t4 = "", n5 = "", t5 = "", n6 = "", t6 = "", n7 = "", t7 = "", n8 = "", t8 = "", n9 = "", t9 = "", n10 = "", t10 = "", n11 = "", t11 = "", n12 = "", t12 = "", n13 = "", t13 = "", n14 = "", t14 = "", n15 = "", t15 = "", n16 = "", t16 = "") ; n should be a pipe-delimited list of valid bitmap filenames, and c should be a color to call transparent.
{
  global
  max := (n16 = "") ? ((n15 = "") ? ((n14 = "") ? ((n13 = "") ? ((n12 = "") ? ((n11 = "") ? ((n10 = "") ? ((n9 = "") ? ((n8 = "") ? ((n7 = "") ? ((n6 = "") ? ((n5 = "") ? ((n4 = "") ? ((n3 = "") ? ((n2 = "") ? 1 : 2) : 3) : 4) : 5) : 6) : 7) : 8) : 9) : 10) : 11) : 12) : 13) : 14) : 15) : 16
  iconheader := "00000100" . switchendianhexshort(numbasechng(max, 10, 16))
  data1 := make_bitmap_header_for_icon(n1) . data . tmapdata(t1, sizeh, sizew)
  dir1 := make_icon_directory(data1, get_starting_offset_icon(max))
  data2 := (max >= 2) ? make_bitmap_header_for_icon(n2) . data . tmapdata(t2, sizeh, sizew) : ""
  dir2 := (max >= 2) ? make_icon_directory(data2, offset) : ""
  data3 := (max >= 3) ? make_bitmap_header_for_icon(n3)data . tmapdata(t3, sizeh, sizew) : ""
  dir3 := (max >= 3) ? make_icon_directory(data3, offset) : ""
  data4 := (max >= 4) ? make_bitmap_header_for_icon(n4)data . tmapdata(t4, sizeh, sizew) : ""
  dir4 := (max >= 4) ? make_icon_directory(data4, offset) : ""
  data5 := (max >= 5) ? make_bitmap_header_for_icon(n5)data . tmapdata(t5, sizeh, sizew) : ""
  dir5 := (max >= 5) ? make_icon_directory(data5, offset) : ""
  data6 := (max >= 6) ? make_bitmap_header_for_icon(n6)data . tmapdata(t6, sizeh, sizew) : ""
  dir6 := (max >= 6) ? make_icon_directory(data6, offset) : ""
  data7 := (max >= 7) ? make_bitmap_header_for_icon(n7)data . tmapdata(t7, sizeh, sizew) : ""
  dir7 := (max >= 7) ? make_icon_directory(data7, offset) : ""
  data8 := (max >= 8) ? make_bitmap_header_for_icon(n8)data . tmapdata(t8, sizeh, sizew) : ""
  dir8 := (max >= 8) ? make_icon_directory(data8, offset) : ""
  data9 := (max >= 9) ? make_bitmap_header_for_icon(n9)data . tmapdata(t9, sizeh, sizew) : ""
  dir9 := (max >= 9) ? make_icon_directory(data9, offset) : ""
  data10 := (max >= 10) ? make_bitmap_header_for_icon(n10)data . tmapdata(t10, sizeh, sizew) : ""
  dir10 := (max >= 10) ? make_icon_directory(data10, offset) : ""
  data11 := (max >= 11) ? make_bitmap_header_for_icon(n11)data . tmapdata(t11, sizeh, sizew) : ""
  dir11 := (max >= 11) ? make_icon_directory(data11, offset) : ""
  data12 := (max >= 12) ? make_bitmap_header_for_icon(n12)data . tmapdata(t12, sizeh, sizew) : ""
  dir12 := (max >= 12) ? make_icon_directory(data12, offset) : ""
  data13 := (max >= 13) ? make_bitmap_header_for_icon(n13)data . tmapdata(t13, sizeh, sizew) : ""
  dir13 := (max >= 13) ? make_icon_directory(data13, offset) : ""
  data14 := (max >= 14) ? make_bitmap_header_for_icon(n14)data . tmapdata(t14, sizeh, sizew) : ""
  dir14 := (max >= 14) ? make_icon_directory(data14, offset) : ""
  data15 := (max >= 15) ? make_bitmap_header_for_icon(n15)data . tmapdata(t15, sizeh, sizew) : ""
  dir15 := (max >= 15) ? make_icon_directory(data15, offset) : ""
  data16 := (max >= 16) ? make_bitmap_header_for_icon(n16)data . tmapdata(t16, sizeh, sizew) : ""
  dir16 := (max >= 16) ? make_icon_directory(data16, offset) : ""
  icondata = %iconheader%%dir1%%dir2%%dir3%%dir4%%dir5%%data1%%data2%%data3%%data4%%data5%00
  converthextobin(icondata, newdata)
  writevartofile(dp, newdata, 0, 0, 0, 0)
}

tmapdata(n, w, h)
{
  local monodata =
  ifexist, %n%
  {
    readfiletovar(n, rawdata, 0, 0, 0)
    convertbintohex(rawdata, monohex)
    monodata := substr(monohex, 125, strlen(monohex) - 126)
  }
  else
  {
    loop, % h * (ceil(1 / 32 * w) * 4)
      monodata = %monodata%00
  }
  return, %monodata%
}

make_bitmap_header_for_icon(n)
{
  global data
  readfiletovar(n, rawdata, 0, 0, 0)
  convertbintohex(rawdata, hex)
  if checkbitmap(n) = 0
    return, -1
  sizew := numbasechng(switchendianhexint(substr(hex, 37, 8) + 0), 16, 10)
  sizeh := numbasechng(switchendianhexint(substr(hex, 45, 8) + 0), 16, 10)
  bitd := substr(hex, 57, 4)
  cip := substr(hex, 93, 8)
  data := substr(hex, 109, strlen(hex) - 110)
  bmp_hsize := 28000000
  bmp_width := switchendianhexint(numbasechng(sizew, 10, 16))
  bmp_height := switchendianhexint(numbasechng(sizeh * 2, 10, 16))
  bmp_planes = 0100
  bmp_bpp := bitd
  bmp_comp = 00000000
  bmp_datasize := switchendianhexint(numbasechng(strlen(data) / 2 + sizeh * (ceil(1 / 32 * sizew) * 4), 10, 16))
  bmp_ppm := switchendianhexlong(0)
  bmp_cip := cip
  bmp_imp := 00000000
  bmp_header = %bmp_hsize%%bmp_width%%bmp_height%%bmp_planes%%bmp_bpp%%bmp_comp%%bmp_datasize%%bmp_ppm%%bmp_cip%%bmp_imp%
  return, %bmp_header%
}

make_icon_directory(idhex, o)
{
  global
  imagesize := round(strlen(idhex) / 2, 0)
  bpp := numbasechng(switchendianhexshort(substr(idhex, 29, 4)), 16, 10)
  ico_width := substr(idhex, 9, 2)
  ico_height := numbasechng(numbasechng(substr(idhex, 17, 2), 16, 10) / 2, 10, 16)
  ico_bpp := substr(idhex, 29, 4)
  ico_colors := (bpp >= 8) ? "00" : ((bpp >= 4) ? 2 ** bpp : "0" . 2 ** bpp)
  ico_res = 00
  ico_planes = 0100
  ico_imagesize := switchendianhexint(numbasechng(strlen(idhex) / 2, 10, 16))
  ico_offset := switchendianhexint(numbasechng(o, 10, 16))
  ico_directory = %ico_width%%ico_height%%ico_colors%%ico_res%%ico_planes%%ico_bpp%%ico_imagesize%%ico_offset%
  offset := o + imagesize
  return %ico_directory%
}


the function to make an icon is called "makeiconfrombitmap(...)." the first parameter is the name of the icon to generate. all of the following pairs of parameters are a normal bitmap (generally a 16 color or 256 color) and a monochrome bitmap (makable with MS Paint) where black means opaque and white means transparent. because icons only have one picture, it is best to use scaled images of the same thing for different resolutions (btw, windows uses 16x16, 24x24, 32x32, and 48x48)
theres still a few glitches to iron out but the icons display properly on my desktop, and i will probably work more on this one, so i hope to eventually fix them.[/code]
_________________
problems := bugs + errors + glitches
code := (problems != 0) ? debug(code) : celebrate()
Back to top
View user's profile Send private message
BoBo²
Guest





PostPosted: Mon Jun 02, 2008 8:23 am    Post subject: Reply with quote

Sounds cool! Cool
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group