#先创建两个类读取bmp和xbm。手头没有足够的xbm资料,无法验证格式%100正确。
class bmp_read():
def __init__(self,bmpfilename):
self._file=self.openbmp(bmpfilename)
self.type =self._file[:2]
self.bf_size =self.hex2ten(self._file[2:6] )
self.bf_off_bits=self.hex2ten(self._file[10:14])
self.width =self.hex2ten(self._file[18:22])
self.height =self.hex2ten(self._file[22:26])
self.planes =self.hex2ten(self._file[26:28])
self.bitcount=self.hex2ten(self._file[28:30])
self.compression=self.hex2ten(self._file[30:34])
self.cprs=self.compression
self.size_image= self.hex2ten(self._file[34:38])
self.x_ppm=self.hex2ten(self._file[38:42])
self.y_ppm=self.hex2ten(self._file[42:46])
self.udcolor=self.hex2ten(self._file[46:50])
self.vipcolor=self.hex2ten(self._file[50:54])
self.data=self._file[self.bf_off_bits:]
def openbmp(self,bmpfilename):
sf=open(bmpfilename,"rb")
c=sf.read()
sf.close()
return c
def hex2ten(self,sth):
a=list(sth)
v=0
for i,k in enumerate(a):
v+=k*(256**i)
return v
#---------------------------
class xbm_read(): # 不是很严谨的代码
def __init__(self,xbmfilename):
self._file=self.openxbm(xbmfilename)
self.w,self.h,self.data=self.findsth()
def openxbm(self,xbmfilename):
sf=open(xbmfilename,"r",encoding="utf-8")
c=sf.readlines()
sf.close()
return c
def findsth(self):
w=None
h=None
dta=None
dtb=None
data=None
for i in self._file:
if ("_width" in i) : w = int(i.split("_width")[1].strip())
elif ("_height" in i) : h = int(i.split("_height")[1].strip())
if w !=None and (h != None): break
for i ,k in enumerate(self._file):
if "{" in k:dta=i ;self._file[i]=k.split("{")[1]
elif "}" in k: dtb=i; self._file[i]=k.split("}")[0]
if dta !=None and ( dtb != None):
data="".join(self._file[dta:dtb+1]).replace("n","")
data=data.split(",")
data=[int(i,16) for i in data if i!=""]
return w,h,data
#==========================实践
#a=bmp_read("f.bmp") # 你的图片,请自备单色位图一张。最好用小一点的。
#data=a.data # 图片内容
#h=a.height
#w_img=a.width
#-------------------------------------- 宽度相关的 数据调整
def ccwb(w_img):
w4=w_img //32 # w_img是原来的图片宽度,但是保存时的 wf,采取对齐策略,所以可能有所“变大”。
restbit=w_img % 32
wf = w4*32 # window 是按照每次4字节来读取图片, 所以 w_img 若不能整除以32,则剩下一些bits
restbyte=restbit // 8 # 剩下的 bits 在 4个字节(32 bits)长度内,假如剩下25 bit,那么还需要3个字节,but...
if restbit !=0: # mod 32 有剩余 否 ?
wf += 32 # Windows 图片处理机制下,自动加白边(对齐4字节),以便增快读取速度
if (restbit % 8) !=0: # 对字节有剩余否?
restbyte+=1
#------------------------------------ 得出结果 宽度
wfb=wf //8 # 按字节计算的存储宽度(文件)
wb= w4*4+restbyte # 我们实际需要的字节宽度。
return wfb,wb
#---------------------------------------辅助函数
def bin2points(bis):
s=bis.replace("0","。").replace("1","回")
return s
def bytes2bin(bys): #字节变*10101000*(这是举例)字符串
s=""
for b in bys:
v=bin(b)[2:]
c=len(v)
s+="0"*(8-c)+v
return s
def rv(s): #反向
s=list(s)
s.reverse()
s="".join(s)
return s
def bins2hex(bis):
b=len(bis)//8
v=[bis[i*8: i*8+8] for i in range(b) ]
v=[int(i,2) for i in v]
v=bytes(v)
x=v.hex("-")
x="0x"+x.replace("-",", 0x")+","
return x
def cxwb(w_img): # 处理xbm 文件的宽度(读取 xbm 数据时)
wfb=w_img//8
if w_img % 8 !=0:
wfb+=1
return wfb ,wfb
def make_xbm_file(w,h,data):
df=open("i_new.xbm","w",encoding="utf-8")
df.write("#define new_width "+str(w)+"n")
df.write("#define new_height "+str(h)+"n" )
df.write("static unsigned char new_bits[] = { n")
df.write(data)
df.write("};n")
print("文件 i_new.xbm --- done ")
#------------------------------------------------------- 打印
def printXbmp(data,w,h,m="p"):
if m=="p": #打印bmp图片
wfb,wb=ccwb(w)
for i in range(h-1,-1,-1): # 好像图像是倒着来记录的,h
v=data[i*wfb:i*wfb+wb]
x=bin2points(bytes2bin(v))
print(x)
elif m=="x": # 打印xbm文件的数据,必须提供相应的xbm参数
wfb,wb=cxwb(w)
for i in range(h):
v=data[i*wfb:i*wfb+wb]
x=bin2points(rv(bytes2bin(v)))
print(x)
elif m=="xf": # 从一般 bmp 图片制作 xbm 文件
wfb,wb=ccwb(w)
s=""
for i in range(h-1,-1,-1):
v=data[i*wfb:i*wfb+wb]
x=bins2hex(rv(bytes2bin(v)))
s+=("t"+x+"n")
make_xbm_file(w,h,s)
print("n")
#--------------------
a=bmp_read("f.bmp") # 你的图片,请自备单色位图一张。最好用小一点的。
data=a.data # 图片内容
h=a.height
w_img=a.width
printXbmp(data,w_img,h,m="p")
#------------------------
b=xbm_read('i_new.xbm')
data=b.data
w=b.w
h=b.h
printXbmp(data,w,h,m="x")
改下前面文章的结果



