1.圖片轉ico(轉自https://blog.csdn.net/c_boy_lu/article/details/49816039,我也沒用過這個)
# -*- coding: utf-8 -*-
import os,sys
from PIL import Image
image_size = [512,256,144,140,128,120,108,100,88,72,48,32,28]
def create_icon():
for size in image_size:
'''pri_image = Image.open("icon.png")
pri_image.thumbnail((size,size))
image_name = "icon_%d.png"%(size)
pri_image.save(image_name)'''
pri_image = Image.open("icon.png")
pri_image.resize((size,size),Image.ANTIALIAS ).save("icom_%d.png"%(size))
if __name__ == "__main__":
create_icon()
我自己
#Python3.7
import PIL.Image as Image
img=Image.open("1.png")
img.resize(32,32).save("1.ico")
2.網上找不到ico的編碼,我們來了解一下編碼
所以網上找了個ico文件
讀取字節碼
ico=open("2_calendar_16px_11084_easyicon.net.ico","rb")
size=10#比特塊大小
line=ico.read(size)#讀
while(line):
print(line)
line=ico.read(size)#讀下一行
發現不好看,轉換byte爲int
ico=open("2_calendar_16px_11084_easyicon.net.ico","rb")
size=1#比特塊大小
line=ico.read(size)#讀
while(line):
print(int.from_bytes(line,byteorder='big'),end="")
print(" ",end="")
line=ico.read(size)#讀下一行
統計一下byte個數
ico=open("2_calendar_16px_11084_easyicon.net.ico","rb")
size=1#比特塊大小
line=ico.read(size)#讀
bytes=0
while(line):
#print(int.from_bytes(line,byteorder='big'),end="")
bytes+=1
#print(" ",end="")
line=ico.read(size)#讀下一行
print(bytes)
結果1150個
而圖片信息
16*16=256,而ico帶透明通道,所以是rgba編碼,256*4=1024。1150-1024=126,估計126是文件頭
ico=open("2_calendar_16px_11084_easyicon.net.ico","rb")
size=4#比特塊大小
line=ico.read(126)#讀頭
print([ i for i in line])
line=ico.read(size)
pixel=0
while(line):
print([ i for i in line])
pixel+=1
line=ico.read(size)#讀下一行
print(pixel)
一般像這樣的點陣圖都是順序的
對應關係:
意味着我錯了,在第一個255往前16*4+1纔是圖片數據的頭
ico=open("2_calendar_16px_11084_easyicon.net.ico","rb")
size=4#比特塊大小
line=ico.read(61)#讀圖片頭
print([ i for i in line])
#讀取圖片數據段
line=ico.read(size)
pixel=0
while(line):
print([ i for i in line])
pixel+=1
if (pixel==256):
break
line=ico.read(size)#讀下一行
#讀取圖片尾
print([ i for i in ico.read(65)])#顯示剩下的
這樣就把數據段抽出來了
後來查了下Python\Python37\Lib\site-packages\PIL的轉換源代碼
Image.py.save()調用了一個ext = os.path.splitext(filename)[1].lower()獲取文件擴展名
IcoImagePlugin.py._save()
_MAGIC = b"\0\0\1\0"
def _save(im, fp, filename):
fp.write(_MAGIC) # (2+2)
sizes = im.encoderinfo.get("sizes",
[(16, 16), (24, 24), (32, 32), (48, 48),
(64, 64), (128, 128), (256, 256)])
width, height = im.size
sizes = filter(lambda x: False if (x[0] > width or x[1] > height or
x[0] > 256 or x[1] > 256) else True,
sizes)
sizes = list(sizes)
fp.write(struct.pack("<H", len(sizes))) # idCount(2)
offset = fp.tell() + len(sizes)*16
for size in sizes:
width, height = size
# 0 means 256
fp.write(struct.pack("B", width if width < 256 else 0)) # bWidth(1)
fp.write(struct.pack("B", height if height < 256 else 0)) # bHeight(1)
fp.write(b"\0") # bColorCount(1)
fp.write(b"\0") # bReserved(1)
fp.write(b"\0\0") # wPlanes(2)
fp.write(struct.pack("<H", 32)) # wBitCount(2)
image_io = BytesIO()
tmp = im.copy()
tmp.thumbnail(size, Image.LANCZOS)
tmp.save(image_io, "png")
image_io.seek(0)
image_bytes = image_io.read()
bytes_len = len(image_bytes)
fp.write(struct.pack("<I", bytes_len)) # dwBytesInRes(4)
fp.write(struct.pack("<I", offset)) # dwImageOffset(4)
current = fp.tell()
fp.seek(offset)
fp.write(image_bytes)
offset = offset + bytes_len
fp.seek(current)
真像大白!!!
再後來事情就變得迷離了,突然想到windows圖標是ico,那麼寫windows用的是C,C++,那麼,帖文檔啥也不說了,果然文檔最簡單。
https://blog.csdn.net/jinzhuojun/article/details/8007586 博客
https://msdn.microsoft.com/en-us/library/ms997538.aspx 微軟