现在的位置: 首页 > 综合 > 正文

保存为 ico 格式

2013年10月03日 ⁄ 综合 ⁄ 共 3026字 ⁄ 字号 评论关闭

几天前 yrt888 就提出了这个问题,今天看到行者的 blog 中用 Ole... 类 api 来保存为 ico 的方法,同时也看到有人留言说只能保存为 16 色的图标,试了一下,确实如此。要将其他格式的图片保存为 24bits 甚至 xp 格式的 32bits 图标,是否真的就那样难呢?到网上查了查,说 ico 文件格式的资料确实不少,可保存为 ico 格式却没几个,唯一一个可用的又是用 c# 写的,且用到了 .NET 中类,这样 vfp 就难以借用这种方法了。但细致研究了一下 ico 文件的格式后发现,其实 ico 格式基本上只是在 bmp 格式的外面加了一层壳,后面再附上一个掩码,如果做成只包含一个图标的 32bits 图标文件也并非太难,所以有了下面的实验品,不过简化了很多处理,比如掩码处理被省略了,这对图标的显示没有影响,只是如果你把它放到桌面上,然后拖动它就会发现有些问题了,不过这不重要,有必要的话再研究一下掩码的自动生成方法就可以了。

运行后,会首先要你指定一个用于转换的原图片文件,这里缺省使用 png 类型的图片,因为通常只有这种图片才会带有 Alpha 通道,不过现在有些 bmp 图片也有 32bits 格式的,当然你也可以选其他类型图片来作原料,不过就很难保证会透明了,gif 如果原来有透明处理也可以,但 jpg 等格式就肯定不会透明;之后再指定要保存的位置和图标文件名即可。

这里缺省保存为 32x32 大小的图标,你可以修改 ICON_SIZE 这个常数,也可以改成一个函数,将 icon_size 作为参数传入;此外,为了简单一点,这里使用了 gdiplus 中的 api 来缩放到指定大小的图片,然后再转成 ico 格式,由于 gdiplus 中缩放方法处理比较简单,所以缩放后的质量并不是很好,如果你对这个很在意,可以参照行者 blog 中的方法来自己处理缩放。

  1. #define ICON_SIZE       32             && 最后要保存的图标尺寸 
  2. declare long GdiplusStartup in gdiplus long @, string, long @
  3. declare long GdiplusShutdown in gdiplus long
  4. declare long GdipLoadImageFromFile in gdiplus string, long @
  5. declare long GdipSaveImageToFile in gdiplus long, string, string, long
  6. declare long GdipDisposeImage in gdiplus long
  7. declare long GdipGetImageThumbnail in gdiplus long, long, long, long @, long, long
  8. store 0 to hToken, nImage, nImage1
  9. nInputBuf = 0h01 + replicate(chr(0), 15)
  10. cEncoder = 0h00F47C55041AD3119A730000F81EF32E
  11. GdiplusStartup(@ hToken, nInputBuf, 0)
  12. GdipLoadImageFromFile(strconv(getfile('png')+chr(0),5), @ nImage)
  13. GdipGetImageThumbnail(nImage, ICON_SIZE, ICON_SIZE, @ nImage1, 0, 0)
  14. GdipDisposeImage(nImage)
  15. cBmpFile = putfile('', '', 'ico')
  16. GdipSaveImageToFile(nImage1, strconv(cBmpFile,5)+chr(0), cEncoder, 0)
  17. GdipDisposeImage(nImage1)
  18. GdiplusShutdown(hToken)
  19. cBmpDat = filetostr(cBmpFile)
  20. erase (cBmpFile)
  21. nMaskSize    = ICON_SIZE * bitand((ICON_SIZE + 31), 0xFFFFFFE0) / 8
  22. nIconDatSize = 4 * ICON_SIZE * ICON_SIZE + nMaskSize
  23. cIconHead = '' ;
  24.   + bintoc(0, '2rs') ;                                       && 保留位
  25.   + bintoc(1, '2rs') + bintoc(1, '2rs') ;                    && id, 图标数
  26.   + bintoc(ICON_SIZE, '1rs') + bintoc(ICON_SIZE, '1rs') ;    && 宽, 高
  27.   + bintoc(0, '1rs') + bintoc(0, '1rs') ;                    && 颜色数, 保留位
  28.   + bintoc(1, '2rs') + bintoc(32, '2rs') ;                   && 位面数, 色深
  29.   + bintoc(len(cBmpDat) - 14 + nMaskSize, 'rs')              && 图标数据尺寸
  30. cIconHead = cIconHead ;
  31.   + bintoc(len(cIconHead)+4, 'rs' )
  32. cBmpHead = '' ;                                              && bmp 头结构大小
  33.   + bintoc(ICON_SIZE, 'rs') + bintoc(2*ICON_SIZE, 'rs') ;    && 宽, 高
  34.   + bintoc(1, '2rs') + bintoc(32, '2rs') ;                   && 位面, 色深
  35.   + bintoc(0, 'rs') ;                                        && 压缩
  36.   + bintoc(nIconDatSize, 'rs') ;                             && 图像数据尺寸
  37.   + bintoc(0, 'rs') + bintoc(0, 'rs') ;                      && x, y, 分辨率
  38.   + bintoc(0, 'rs') + bintoc(0, 'rs')                        && 颜色数, 关键色数
  39. cBmpHead = ;
  40.   bintoc(len(cBmpHead)+4, 'rs') + cBmpHead
  41. cIconDat = cIconHead + cBmpHead ;
  42.   + substr(cBmpDat, 55 ) ;                                  && 位图数据
  43.   + replicate( chr(0xff), nMaskSize )                       && 掩码
  44. strtofile(cIconDat, cBmpFile)
  45. return

...

抱歉!评论已关闭.