比这篇新的文章:
Codee#6095
比这篇旧的文章: Codee#6093
作者: 半瓶墨水, 点击416次, 评论(0), 收藏者(1), , 打分:
所有评论,共0条:( 我也来说两句)
比这篇旧的文章: Codee#6093
ICON Creater from RGBa array-生成图标文件,支持24位和32位图片
语言: Python, 标签: icon ico 图标 2009/09/15发布 6个月前更新 更新记录作者: 半瓶墨水, 点击416次, 评论(0), 收藏者(1), , 打分:
001 #! /usr/bin/env python
002 # -*- coding: utf-8 -*-
003 #
004 # windows icon file(.ico) and cursor file(.cur) generator/writer from RGB(a) array
005 #
006 # NOTICE: one image per file *only*, 16x16 or 32x32 or 48x48 or 64x64 *only*
007 # Support 24 bit & 32 bit(RGB + alpha)
008 #
009 # Copyright 2009 半瓶墨水
010 # 署名 & 非商业性使用 & 相同方式共享 ( http://creativecommons.org/licenses/by-nc-sa/2.5/cn/ )
011 #
012 # About Author
013 # Blog( http://2maomao.com/blog/ )
014 # Website( http://fayaa.com/tool/favicon/ )
015 # Contact me via email
016 #
017 # References:
018 # [1] http://en.wikipedia.org/wiki/Ico_Format
019 # [2] http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap
020 # [3] http://support.microsoft.com/kb/83034
021 # [4] http://msdn.microsoft.com/en-us/library/ms997538(loband).aspx
022 # [5] http://www.martinreddy.net/gfx/2d/BMP.txt
023 # [6] http://code.google.com/p/casadebender/source/browse/python/PIL/Win32IconImagePlugin.py
024 # [7] http://www.osphp.com.cn/read.php/290.htm
025
026
027 # data: a size*size of (r,g,b,t) tuples, t for tansparency(if True)
028 # (r,g,b,a) if bpp is 32
029 # size: could be 16 or 32 or 48 or 64, other value NOT supported
030 # bpp: bits per pixel, could *only* be 24 or 32!
031 # return: an "array" of BYTES which, if write to file, is a size*size ico file
032 def genico(data, size=16, bpp=24):
033 from array import array
034 a = array('B')
035 #header(ref1&5)
036 a.extend((0,0, 1,0, 1,0)) #reserved*2, icon,0, 1 image per-file,0
037 #directory(ref1&5&7)
038 imglen = 40+size*(size*3 + (size+16)/32*32/8) #image-part length in bytes
039 #!hack! AND bits align to 32 bits per line
040 #!shit! MSDN says nothing about this
041 if bpp == 32:
042 imglen += size*size #1 more byte for alpha value of each pixel
043 a.extend((size,size, 0,0, 1,0, bpp,0)) #w,h, reserved*2, 1plane*2, bpp*2
044 a.extend((imglen&0xff,imglen>>8,0,0, 22,0,0,0)) #bitmap-size*4,22B-offset*4
045 #image BITMAPINFOHEADER(ref5)
046 a.extend((40,0,0,0)) #size of data(contains header)*4
047 a.extend((size,0,0,0, size*2,0,0,0))#w*4, (h+h)*4 (!shit hack! XOR+AND)
048 a.extend((1,0, bpp,0, 0,0,0,0, 0,0,0,0)) #1 plane*2, 24 bits*2, no compress*4, rawBMPsize(no compress so 0)*4
049 a.extend((0,1,0,0, 0,1,0,0)) #horizontal*4/vertical*4 resolution pixels/meter(WTF?)
050 a.extend((0,0,0,0, 0,0,0,0)) #colors fully used, all are important
051 #!no planes
052 #image content(ref1&5), XOR+AND bitmaps
053 AND = array('B')
054 vand = 0
055 vcnt = 0
056 #remember that bitmap format is reversed in y-axis
057 for y in range(size-1,-1,-1):
058 for x in range(0, size):
059 b,g,r,t_or_a = data[y*size+x]
060 a.extend((r,g,b))
061 if bpp == 32:
062 a.append(t_or_a)
063 vcnt+=1
064 vand<<=1
065 if (bpp==24 and t_or_a) or (bpp==32 and t_or_a<128):
066 vand |= 1
067 if vcnt==8:
068 AND.append(vand)
069 vcnt=0
070 vand=0
071 #!hack! AND bits align to 32 bits per line, !shit! MSDN says nothing about this
072 AND.extend([0] * ((32-size%32)%32/8))
073 a.extend(AND)
074 return a
075
076 # x,y indicate the hotspot position
077 # simply set the type/hotspot(x&y) after generates the icon
078 def gencur(data, size=16, bpp=24, x=0, y=0):
079 a = genico(data, size, bpp)
080 a[3], a[10], a[12] = 2, x, y
081 return a
082
083 #---------------testing-------------------
084
085 def test_ico(fn, cofunc, wh, bpp=24):
086 data = []
087 for i in range(wh*wh):
088 data.append(cofunc(i))
089 icoflow = genico(data, wh, bpp)
090 f = open(fn, "wb")
091 icoflow.tofile(f)
092 f.close()
093
094 # test it!
095 if __name__ == "__main__":
096 wh = 16
097 av = lambda i: i/wh*256/wh
098 #16x16 red
099 test_ico("red_green_16.ico", lambda i: (av(i), (i%wh)*256/wh, 0, 0), wh)
100 #16x16 green and transparent
101 test_ico("green_16.ico", lambda i: (0, av(i), 0, (i%wh)>wh/2), wh)
102 wh = 32
103 #32x32 blue
104 test_ico("blue_32_trans.ico", lambda i: (0, 0, av(i), (i%wh)<wh/2), wh)
105 #32x32 gray and transparent
106 test_ico("gray_32.ico", lambda i: (av(i), av(i), av(i), 0), wh)
107 #32x32 blue and alpha
108 test_ico("blue_32_alpha.ico", lambda i: (0, 0, av(i), av(i)), wh, 32)
002 # -*- coding: utf-8 -*-
003 #
004 # windows icon file(.ico) and cursor file(.cur) generator/writer from RGB(a) array
005 #
006 # NOTICE: one image per file *only*, 16x16 or 32x32 or 48x48 or 64x64 *only*
007 # Support 24 bit & 32 bit(RGB + alpha)
008 #
009 # Copyright 2009 半瓶墨水
010 # 署名 & 非商业性使用 & 相同方式共享 ( http://creativecommons.org/licenses/by-nc-sa/2.5/cn/ )
011 #
012 # About Author
013 # Blog( http://2maomao.com/blog/ )
014 # Website( http://fayaa.com/tool/favicon/ )
015 # Contact me via email
016 #
017 # References:
018 # [1] http://en.wikipedia.org/wiki/Ico_Format
019 # [2] http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap
020 # [3] http://support.microsoft.com/kb/83034
021 # [4] http://msdn.microsoft.com/en-us/library/ms997538(loband).aspx
022 # [5] http://www.martinreddy.net/gfx/2d/BMP.txt
023 # [6] http://code.google.com/p/casadebender/source/browse/python/PIL/Win32IconImagePlugin.py
024 # [7] http://www.osphp.com.cn/read.php/290.htm
025
026
027 # data: a size*size of (r,g,b,t) tuples, t for tansparency(if True)
028 # (r,g,b,a) if bpp is 32
029 # size: could be 16 or 32 or 48 or 64, other value NOT supported
030 # bpp: bits per pixel, could *only* be 24 or 32!
031 # return: an "array" of BYTES which, if write to file, is a size*size ico file
032 def genico(data, size=16, bpp=24):
033 from array import array
034 a = array('B')
035 #header(ref1&5)
036 a.extend((0,0, 1,0, 1,0)) #reserved*2, icon,0, 1 image per-file,0
037 #directory(ref1&5&7)
038 imglen = 40+size*(size*3 + (size+16)/32*32/8) #image-part length in bytes
039 #!hack! AND bits align to 32 bits per line
040 #!shit! MSDN says nothing about this
041 if bpp == 32:
042 imglen += size*size #1 more byte for alpha value of each pixel
043 a.extend((size,size, 0,0, 1,0, bpp,0)) #w,h, reserved*2, 1plane*2, bpp*2
044 a.extend((imglen&0xff,imglen>>8,0,0, 22,0,0,0)) #bitmap-size*4,22B-offset*4
045 #image BITMAPINFOHEADER(ref5)
046 a.extend((40,0,0,0)) #size of data(contains header)*4
047 a.extend((size,0,0,0, size*2,0,0,0))#w*4, (h+h)*4 (!shit hack! XOR+AND)
048 a.extend((1,0, bpp,0, 0,0,0,0, 0,0,0,0)) #1 plane*2, 24 bits*2, no compress*4, rawBMPsize(no compress so 0)*4
049 a.extend((0,1,0,0, 0,1,0,0)) #horizontal*4/vertical*4 resolution pixels/meter(WTF?)
050 a.extend((0,0,0,0, 0,0,0,0)) #colors fully used, all are important
051 #!no planes
052 #image content(ref1&5), XOR+AND bitmaps
053 AND = array('B')
054 vand = 0
055 vcnt = 0
056 #remember that bitmap format is reversed in y-axis
057 for y in range(size-1,-1,-1):
058 for x in range(0, size):
059 b,g,r,t_or_a = data[y*size+x]
060 a.extend((r,g,b))
061 if bpp == 32:
062 a.append(t_or_a)
063 vcnt+=1
064 vand<<=1
065 if (bpp==24 and t_or_a) or (bpp==32 and t_or_a<128):
066 vand |= 1
067 if vcnt==8:
068 AND.append(vand)
069 vcnt=0
070 vand=0
071 #!hack! AND bits align to 32 bits per line, !shit! MSDN says nothing about this
072 AND.extend([0] * ((32-size%32)%32/8))
073 a.extend(AND)
074 return a
075
076 # x,y indicate the hotspot position
077 # simply set the type/hotspot(x&y) after generates the icon
078 def gencur(data, size=16, bpp=24, x=0, y=0):
079 a = genico(data, size, bpp)
080 a[3], a[10], a[12] = 2, x, y
081 return a
082
083 #---------------testing-------------------
084
085 def test_ico(fn, cofunc, wh, bpp=24):
086 data = []
087 for i in range(wh*wh):
088 data.append(cofunc(i))
089 icoflow = genico(data, wh, bpp)
090 f = open(fn, "wb")
091 icoflow.tofile(f)
092 f.close()
093
094 # test it!
095 if __name__ == "__main__":
096 wh = 16
097 av = lambda i: i/wh*256/wh
098 #16x16 red
099 test_ico("red_green_16.ico", lambda i: (av(i), (i%wh)*256/wh, 0, 0), wh)
100 #16x16 green and transparent
101 test_ico("green_16.ico", lambda i: (0, av(i), 0, (i%wh)>wh/2), wh)
102 wh = 32
103 #32x32 blue
104 test_ico("blue_32_trans.ico", lambda i: (0, 0, av(i), (i%wh)<wh/2), wh)
105 #32x32 gray and transparent
106 test_ico("gray_32.ico", lambda i: (av(i), av(i), av(i), 0), wh)
107 #32x32 blue and alpha
108 test_ico("blue_32_alpha.ico", lambda i: (0, 0, av(i), av(i)), wh, 32)
所有评论,共0条:( 我也来说两句)
代码
