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

【Python】实现字体中字符的点阵转换

2018年04月23日 ⁄ 综合 ⁄ 共 8009字 ⁄ 字号 评论关闭

以下代码实现的是:紧凑转换。

其中使用的Image和ImageGrab模块需要安装PIL库。

 

from Tkinter import *
from tkMessageBox import *
import time
import Image
import ImageGrab

# some constant
HEIGHT   = 20
WIDTH    = 20
TRUE     = 1
FALSE    = 0
INVALID  = 0
NONSEL   = 1
SELECTED = 2

# some parameters
ENTRY_WIDTH = 58

# launch tk
root=Tk();root.title('Dot matrix')

class App(Frame):
    def __init__(self,master):
        Frame.__init__(self)
        # bind event
        master.bind('<Button-1>',self.LeftClick)
        master.bind('<Button-2>',self.MiddleClick)
        master.bind('<Button-3>',self.RightClick)
        master.bind('<Key-F6>',self.Generate)
        master.bind('<Key-F7>',self.Clear)

        # set color
        self.invalid_color="#%02x%02x%02x" % (255,255,255)
        self.nonsel_color="#%02x%02x%02x" % (204,232,207)
        self.selected_color="#%02x%02x%02x" % (250,0,0)

        # set height
        self.height_label=Label(master,text='Height: ',bg='green',fg='black')
        self.height=IntVar()
        self.height_entry=Entry(master,width=ENTRY_WIDTH,textvariable=self.height)
        self.height_entry.bind('<Return>',self.UpdateSize)
        self.height.set(HEIGHT)

        # set width
        self.width_label=Label(master,text='Width : ',bg='green',fg='black')
        self.width=IntVar()
        self.width_entry=Entry(master,width=ENTRY_WIDTH,textvariable=self.width)
        self.width_entry.bind('<Return>',self.UpdateSize)
        self.width.set(WIDTH)

        # output code
        self.output_label=Label(master,text='Output: ',bg='green',fg='black')
        self.output_text=Text(master,height=8,width=ENTRY_WIDTH)
        self.output_scroll=Scrollbar(master,command=self.output_text.yview)
        self.output_text.configure(yscrollcommand=self.output_scroll.set)

        # arrange space
        self.height_label.grid(row=1,column=WIDTH,columnspan=2)
        self.height_entry.grid(row=1,column=WIDTH+2,columnspan=1)
        self.width_label.grid(row=2,column=WIDTH,columnspan=2)
        self.width_entry.grid(row=2,column=WIDTH+2,columnspan=1)
        self.output_label.grid(row=HEIGHT-6,column=WIDTH,columnspan=2)
        self.output_text.grid(row=HEIGHT-6,column=WIDTH+2,rowspan=6,columnspan=2)
        self.output_scroll.grid(row=HEIGHT-6,column=WIDTH+4,rowspan=6,columnspan=2,sticky=N+E+S+W)

        # store the value
        self.BlockList=[];self.LabelList=[]
        self.BlockRowList=[];self.LabelRowList=[]
        row=0;col=0
        for i in range(HEIGHT*WIDTH):
            L=Label(master,text='    ',bg='black',fg='white',relief=GROOVE,bd=1)
            L.grid(row=row,column=col,sticky=N+E+S+W,ipadx=2,ipady=2)
            L.row=row;L.col=col;L.status=INVALID
            self.BlockRowList.append(0);self.LabelRowList.append(L)
            col=col+1
            if col>=WIDTH:
                row=row+1;col=0
                self.BlockList.append(self.BlockRowList)
                self.LabelList.append(self.LabelRowList)
                self.BlockRowList=[];self.LabelRowList=[]

        # init
        self.Clear(0)

        # init automatic information
        #self.mid_index = 0
        self.counter = 0
        self.AutoInfoList=[[1,0],[2,0],[3,0],[4,0],[5,0],[1,1],[2,2],[3,1],
                           [1,4],[2,4],[3,4],[4,4],[5,4],[1,5],[2,6],[3,5],
                           [4,6],[5,6],[1,8],[1,9],[1,10],[2,8],[3,8],[4,8],
                           [5,8],[5,9],[5,10],[3,9],[1,14],[1,13],[2,12],[3,12],
                           [3,13],[3,14],[4,14],[5,13],[5,12],[1,18],[1,17],[2,16],
                           [3,16],[3,17],[3,18],[4,18],[5,17],[5,16],[7,0],[7,1],
                           [7,2],[8,0],[9,0],[10,0],[11,0],[9,1],[7,4],[7,5],[7,6],
                           [8,6],[9,6],[9,5],[10,5],[11,5],[7,12],[7,13],[7,14],[8,13],
                           [9,13],[10,13],[11,13],[7,17],[8,16],[9,16],[10,16],[11,17],
                           [10,18],[9,18],[8,18],[13,2],[13,1],[14,0],[15,0],[15,1],[15,2],
                           [16,2],[17,1],[17,0],[13,4],[13,5],[13,6],[14,5],[15,5],[16,5],
                           [17,5],[13,9],[14,8],[15,8],[16,8],[17,8],[14,10],[15,10],[16,10],
                           [17,10],[15,9],[13,12],[14,12],[15,12],[16,12],[17,12],[13,13],
                           [14,14],[15,13],[16,14],[17,14],[13,16],[13,17],[13,18],[14,17],
                           [15,17],[16,17],[17,17]]
        
        # timer
        self.time=1000
        self.after(self.time,self.OnTimer)

    def __del__(self):
        pass

    def OnTimer(self):
        ''' for display animation
        if self.mid_index <= WIDTH/2:
            if self.mid_index != 0:
                for i in range(2*self.mid_index):
                    self.UnFill(HEIGHT/2 - self.mid_index + i, WIDTH/2 - self.mid_index)
                    self.UnFill(HEIGHT/2 - self.mid_index + i, WIDTH/2 + self.mid_index - 1)
                for i in range(2*self.mid_index - 2):
                    self.UnFill(HEIGHT/2 - self.mid_index, WIDTH/2 - self.mid_index + i + 1)
                    self.UnFill(HEIGHT/2 + self.mid_index - 1, WIDTH/2 - self.mid_index + i + 1)
            self.mid_index += 1
            self.after(50,self.OnTimer)
            return
        '''
        if (self.counter >= len(self.AutoInfoList)): return
        self.Fill(self.AutoInfoList[self.counter][0], self.AutoInfoList[self.counter][1])
        self.counter += 1
        self.after(50,self.OnTimer)    

    def LeftClick(self,event):
        try:
            grid_info = event.widget.grid_info()
            i = grid_info["row"]; j = grid_info["column"]
            if self.LabelList[int(i)][int(j)].status != INVALID:
                self.Fill(int(i),int(j))
                # for autoinfo: L = [int(i), int(j)]
                # for autoinfo: self.AutoInfoList.append(L)
        except:
            pass
        
    def MiddleClick(self,event):
        self.RightClick(event)
        ''' for autoinfo: 
        string_info = ""
        for i in range(len(self.AutoInfoList)):
            string_info += "[%d,%d]," % (self.AutoInfoList[i][0], self.AutoInfoList[i][1])
        self.output_text.delete(1.0,END)
        self.output_text.insert(END,string_info)
        '''
        pass

    def RightClick(self,event):
        try:
            grid_info = event.widget.grid_info()
            i = grid_info["row"]; j = grid_info["column"]
            if self.LabelList[int(i)][int(j)].status != INVALID:
                self.UnFill(int(i),int(j))
        except:
            pass

    def UpdateSize(self,event):
        for i in range(HEIGHT):
            for j in range(WIDTH):
                if (i < self.height.get()) and (j < self.width.get()):
                    if self.LabelList[int(i)][int(j)].status == INVALID:
                        self.UnFill(i,j)
                else:
                    self.Invalid(i,j)
    
    def Clear(self,event):
        for i in range(HEIGHT):
            for j in range(WIDTH):
                self.Invalid(i,j)
        #self.height.set(HEIGHT)
        #self.width.set(WIDTH)
        for i in range(self.height.get()):
            for j in range(self.width.get()):
                self.UnFill(i,j)

    def Generate(self,event):
        font_height = self.height.get()
        font_width = self.width.get()

        font_byte_list = []
        byte_tmp = 0
        for i in range(font_height * font_width):
            row = i % font_height
            col = i / font_height
            byte_index = i % 8;
            byte_tmp += self.BlockList[row][col] << byte_index
            if (i+1)%8 == 0:
                font_byte_list.append(byte_tmp)
                byte_tmp = 0

        if (font_height * font_width) % 8 != 0:
            font_byte_list.append(byte_tmp)

        # output info
        string_info = ""
        string_info += "%d, /**/" % font_width
        for i in range(len(font_byte_list)-1):
            string_info += "0x%02X, " % font_byte_list[i]
        string_info += "0x%02X" % font_byte_list[len(font_byte_list)-1]
        self.output_text.delete(1.0,END)
        self.output_text.insert(END,string_info)

    def Fill(self,i,j):
        self.BlockList[i][j]=1
        self.LabelList[i][j].status=SELECTED
        self.LabelList[i][j].config(relief=GROOVE,bg=str(self.selected_color),bd=1)

    def UnFill(self,i,j):
        self.BlockList[i][j]=0
        self.LabelList[i][j].status=NONSEL
        self.LabelList[i][j].config(relief=GROOVE,bg=str(self.nonsel_color),bd=1)

    def Invalid(self,i,j):
        self.BlockList[i][j]=0
        self.LabelList[i][j].status=INVALID
        self.LabelList[i][j].config(relief=GROOVE,bg=str(self.invalid_color),bd=1)

    def LoadBmp(self):
        im = Image.open("D:\\Dir\\Example.bmp")
        if isinstance(im, Image.Image):
            width, height = im.size
            if (width > 20) or (height > 20):
                pass
            else:
                self.width.set(width)
                self.height.set(height)
                self.UpdateSize(0)
                pix = im.load()
                for x in range(width):
                    for y in range(height):
                        if pix[x, y] == (255, 255, 255):
                            self.UnFill(y, x)
                        else:
                            self.Fill(y, x)
                #generate the code
                self.Generate(0)
        else:
            pass

    def HelpInfo(self):
        string_info = "Usage:\r\n\r\n" + \
                      "Use F6 or menu(Operation->Generate code) to generate code\r\n" + \
                      "Use F7 or menu(Operation->Clear grid) to clear the grid\r\n" + \
                      "Use mouse left click to select one grid\r\n" + \
                      "Use mouse right click to cancel the select\r\n" + \
                      "When modify the Height or Width value, press 'Enter' Key to take effect\r\n" + \
                      "\r\n\r\nIf you have any problem, please feel free to contact:\r\n" + \
                      "example@example.com\r\n"
        showinfo('Help...', string_info)        

    def AboutInfo(self):
        string_info = "Version: 1.0                                        \r\n" + \
                      "\r\n\r\nCompany\r\n" + \
                      "Copyright (C) 2011\r\n"
        showinfo('About...', string_info)

# define the menu method
def LoadFont():
    pass

def LoadBmp():
    app.LoadBmp()

def Generate():
    app.Generate(0)

def Clear():
    app.Clear(0)

def HelpInfo():
    app.HelpInfo()

def AboutInfo():
    app.AboutInfo()

# menu
mainmenu=Menu(root)
root['menu']=mainmenu
loadmenu=Menu(mainmenu)
mainmenu.add_cascade(label='File',menu=loadmenu)
loadmenu.add_command(label='Load font',command=LoadFont)
loadmenu.add_command(label='Load bmp',command=LoadBmp)
loadmenu.add_separator()
loadmenu.add_command(label='Exit',command=root.quit)
operationmenu=Menu(mainmenu)
mainmenu.add_cascade(label='Operation',menu=operationmenu)
operationmenu.add_command(label='Generate code',command=Generate)
operationmenu.add_command(label='Clear grid',command=Clear)
helpmenu=Menu(mainmenu)
mainmenu.add_cascade(label='Help',menu=helpmenu)
helpmenu.add_command(label='Help...',command=HelpInfo)
helpmenu.add_command(label='About Dot matrix...',command=AboutInfo)

# main app object
app=App(root)
root.mainloop()

# end


抱歉!评论已关闭.