字體在線轉換器生成器:花里胡哨文字生成器-字體教程免费ppt模版下载-道格办公

花里胡哨文字生成器

很有趣!那麼,您想了解如何使用Python實現花哨文字生成器嗎?

基於Python實現花里胡哨文字生成器

在瀏覽網頁的過程中,時常會看到各種“不同尋常”的文字,形如:

這些文字總會在普通文字的基礎上,附帶許多奇特的符號。其基本原理是Unicode的結合附加符號與普通文字的疊加,想要製作一個這樣的文字生成器,首先就需要了解這樣的文字是怎麼使用Unicode編碼得到的

基本理論

Unicode的作用

最開始的時候,人們使用長度僅1字節的ASCII碼來表示128種字符,其中每個字符都對應一個編碼,例如:二進制編碼01000001 2 _2 2表示字符'A',則在程序中,字符'A'就是用01000001這樣的二進制序列來保存的

後來,隨著需求的增加,只能表示128種字符的ASCII碼逐漸地“不夠用”了:ASCII碼顯然是沒有包含中文、日文、韓文這些文字的,如果要對這些字進行編碼,就需要單獨制定一種新的編碼規則,於是Unicode由此誕生

Unicode使用了更多的字節,將全球各地的語言文字都包含了進去。這樣一來,在Unicode的規則之下,任何國家的文字就都可以有一個對應的編碼了。也就是說,使用Unicode後,就可以在程序中使用各國語言(而非一定要是ASCII碼規定的128種字符之一)了

Unicode結合附加符號

Unicode編碼中,有一個分類叫做“結合附加符號”,這便是這些奇形怪狀的文字的“萬惡之源”:將普通的文字與這些結合附加符號相結合,就會發生一些可能之前從來沒有見過的奇觀

打開python的idle界面,輸入:

sss = "\u0041\u030A"print(sss)

可以觀察到這樣的現象:

注意到不僅是輸出了一個A,而且還在A的上面多了一個圓! \u0041是A的Unicode編碼,而\u030A則是一個結合附加符號" ∘ \circ ∘",當這兩個符號結合起來的時候,圓圈就不會單獨占一個位置,而是與A相互結合了起來!

如果將這個\u030A複製多次,則可以不斷地在A的上方生成越來越多的圓,從而起到“穿屏”的效果:

上述界面是在瀏覽器的開發者工具中的Console運行的結果,而在Python的idle中,顯示的文字是有高度限制的,所以基本上就只保留了第一層的圈,導致視覺效果並不好。實際上,在qq和微信的聊天界面中,也限制了文字的高度,所以復制進去最多就只能看到四五層,在視覺上並不夠震撼

除了圓圈之外,還有其他的很多結合附加符號,他們都可以與前面那個文字相疊加。結合附加符號的Unicode編碼位於第0平面(具體概念沒了解,但用\u開頭表示就是了)的0300-036F之間,共有112種字符,在https://unicode-table.com/cn/ blocks/combining-diacritical-marks/這個網址上可以搜索這些Unicode碼所對應的符號具體都是些啥,對後續的花里胡哨的選擇很有幫助

程序設計思路

在簡單地提及了關於Unicode的內容後,現在就可以設計一個這樣的文字的生成器了

整理一下目前已知的信息:
  1、普通文字+Unicode結合附加符號=在普通文字上追加符號
  2、Unicode結合附加符號的編碼位於第0平面的0300-036F之間,即編碼在\u0300-\u036F之間

因此,如果想要在文字周圍加上一堆奇怪的符號的話,只要在每個字後面都加上這些Unicode結合符號就行了。 Unicode符號加的越多,看起來就越亂(經實測發現,有些符號會往上疊加,而有些符號則是往下疊加):

這樣,在程序中的思路就很清晰了:先讓用戶輸入一個字符串,然後依次遍歷此字符串中的每個字符,在每個字符後面都加入一定數量的Unicode結合符號。最後,再對新的字符串進行輸出就可以了。偽代碼表示如下:

process convertStr(string)	newString <- "" // 初始化一個空串	for i <- 1 to length(string)		randomUnicode <- 隨機生成指定數量的Unicode結合符號對應編碼		newString < ;- newString + string[i] + randomUnicode    end for    return newString

關於Unicode的隨機生成,由於對這112個結合符號不是很了解,所以在這裡就直接在\u0300-\u036F之間隨機選取了。此外,應該還可以讓用戶指定這些結合符號的密度(放在同一個文字上的結合符號數),不然搞太少了沒效果,太多了可能又會爆屏(前幾年在QQ群有看到過疑似是用了大量Unicode結合符號的消息,結果90%的人看到那條消息後,QQ都閃退了……)

有了思路之後,接下來就是實現了

程序實現

分析

用戶的操作是在圖形界面進行的,因此,首先需要一個邊界類:用戶接口類。而關於字符串的處理,可以單獨使用一個控制類來實現,因此,可以再添加一個控制類:字符串處理類。對應的類圖如下所示:

設計

這兩個類之間的主要交互只有一個:用戶接口類向字符串處理類發送一個字符串,讓字符串處理類對字符串進行加工,隨後接收加工後的字符串

由此,給字符串處理類分配方法:convertString(str, density)——字符串加工,給用戶接口類分配方法:convert(str, density)——將字符串發送給字符串處理類,讓後者對字符串進行加工並返回加工後的字符串

此外,字符串是從用戶接口類輸入的,因為長度通常都很小,不需要單獨作為一個實體類而存在,所以可以直接作為用戶接口類的一個成員。綜上所述,構造的類圖如下:

實現

控制類ProString

首先構造控制類ProString,其方法也只有一個,就是上述偽代碼中,過程convertStr(string, density)的實現。新建文件ProString.py:

import randomclass ProString:        '''Process string receive from user's interface class'''    @staticmethod    def convertString(string, density):        newString = ""        lengthOfStr = len(string)        for i in range(lengthOfStr) :            randomUnicode = ""            for j in range(density):                randomUnicode += ("\\u03" + str(int(random.random() * 7)) + str([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'][int(random.random() * 16)]))            # 區分出字母、數字if('a' <= string[i] <= 'z' or 'A' <= string[i] <= 'Z' or '0' <= string[i] <= '9'):                part = string[i]            else:                part = str(string[i].encode("unicode_escape"))[-7:-1]            newString += (part + randomUnicode)        return newString< /code>

因為各種坑爹的問題,字母和數字需要單獨被區分開來,而漢字則需要先轉換為unicode碼的字符形式,所以才有了非常費解的那段if-else語句

而randomUnicode的生成比較地笨,但最直接的能想到的就是這個方式了……

隨意編寫一個test.py來調用這個過程:

from ProString import *a = ProString.convertString("aaa是", 10)print(a)

得到結果:

a\u0363\u032D\u036B\u0314\u032F\u030E\u0359\u0317\u0337\u030Da\u0328\u0322\u0319\u0309\u035E\u0356\u0356\u0321\u033D\u0349a\u033B\ u0331\u036A\u0306\u030A\u0306\u0317\u0325\u032E\u0306\u662f\u032F\u036E\u0323\u034B\u0349\u0351\u032D\u0369\u0322\u0323

這正是想要的返回結果,將其複製到瀏覽器開發者工具的Console上查看效果:

漢字沒有顯示出來,但是不要緊,在其他地方還是可以正常顯示的

接下來再到用戶接口類:

用戶接口類Main

此處使用qt對圖形界面進行設計,首先是一個歸納出的模板:

import sysfrom PySide2.QtUiTools import QUiLoaderfrom PySide2.QtWidgets import QApplicationfrom PySide2.QtCore import QFile, QIODeviceif __name__ == "__main__":    app = QApplication(sys.argv)    ui_file_name = "form.ui"    ui_file = QFile (ui_file_name)    if not ui_file.open(QIODevice.ReadOnly):        print("Cannot open {}: {}".format(ui_file_name, ui_file.errorString()))        sys.exit(-1)    loader = QUiLoader()    window = loader.load(ui_file)    ui_file.close()    if not window:        print(loader.errorString())        sys.exit(-1)    window.show()    sys.exit(app.exec_()) 

使用這段代碼,就可以在運行Main.py的時候,讓python加載一個名為form.ui的圖形化界面文件,並將其打開

現在,先設計圖形界面form.ui。這個過程是在qt creator中完成的:

qt creator能夠提供一個良好的可視化界面設計環境,並且還是有開源(免費)版的,非常值得一試

設計出的窗口界面如下:

隨後,在Main.py中,添加調用ProString.convertString的方法:

def convert():    inputString = window.textEdit.toPlainText()    # 排除空串if(inputString == ""):        return    # 排除非法輸入的符號密度density = window.lineEdit.text() try:        density = int(density)    except:        window.plainTextEdit.setPlainText("符號密度應該是數字!")        return    # 正常執行outputString = ProString.convertString(inputString, density)    outputString = outputString.encode("utf-8" ).decode("unicode_escape")    window.plainTextEdit.setPlainText(outputString)

並將此方法關聯到按鈕上:

window.pushButton.clicked.connect(convert)

到此,生成器的製作就完成了,下面是運行效果:

效果展示

放在QQ中嘗試:

ohhhhhhhhhhhhhhhhhh

經實測發現,如果要保證可讀性,符號密度設置為8就差不多了,再多一些就會影響文字的閱讀了……

最後,在弄完後才發現,在QQ裡面只要多換幾行,就可以讓下面幾行的符號頂到最頂上,可以用這個方式來彌補高度限制……

源碼

form.ui

<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>widget</class> <widget class="QWidget" name="widget">  < ;property name="geometry">   <rect>    <x>0</x>    <y>0</y>    <width>1000</width>    <height>750</height>   < ;/rect>  </property>  <property name="minimumSize">   <size>    <width>1000</width>    <height>750</height>   </size>  </property> ;  <property name="maximumSize">   <size>    <width>1000</width>    <height>750</height>   </size>  </property>  <property name="windowTitle ">   <string>Form</string>  </property>  <widget class="QPushButton" name="pushButton">   <property name="geometry">    <rect>     <x> 840</x>     <y>10</y>     <width>151</width>     <height>61</height>    </rect>   </property>   <property name="font" >    <font>     <family>楷體</family>     <pointsize>20</pointsize>    </font>   </property>   <property name="text">    <string>生成</string>   </property>  </widget>  <widget class="QLineEdit" name="lineEdit">   <property name="geometry">    <rect>     <x>720< /x>     <y>10</y>     <width>61</width>     <height>61</height>    </rect>   </property>   <property name="font"> <font>     <pointsize>20</pointsize>    </font>   </property>   <property name="text">    <string>10</string>   </property>   <property name="maxLength">    <number>2</number>   </property>  </widget>  <widget class="QLabel" name="label">   <property name="geometry"> ;    <rect>     <x>540</x>     <y>10</y>     <width>181</width>     <height>61</height>    </rect>   </property> ;   <property name="font">    <font>     <family>楷體</family>     <pointsize>20</pointsize>    </font>   </property>   <property name=" text">    <string>符號密度</string>   </property>  </widget>  <widget class="QLabel" name="label_2">   <property name="geometry"> <rect>     <x>10</x>     <y>10</y>     <width>211</width>     <height>61</height>    </rect>   </property> <property name="font">    <font>     <family>楷體</family>     <pointsize>20</pointsize>    </font>   </property>   <property name="text ">    <string>待轉換文本</string>   </property>  </widget>  <widget class="QTextEdit" name="textEdit">   <property name="geometry"> <rect>     <x>220</x>     <y>10</y>     <width>311</width>     <height>61</height>    </rect>   </property> <property name="font">    <font>     <pointsize>12</pointsize>    </font>   </property>  </widget>  <widget class="QPlainTextEdit" name="plainTextEdit ">   <property name="geometry">    <rect>     <x>10</x>     <y>80</y>     <width>981</width>     <height>661< /height>    </rect>   </property>   <property name="font">    <font>     <pointsize>20</pointsize>    </font>   </property>  </widget> ; </widget> <resources/> <connections/></ui>

Main.py
import sysfrom PySide2.QtUiTools import QUiLoaderfrom PySide2.QtWidgets import QApplicationfrom PySide2.QtCore import QFile, QIODevicefrom ProString import *def convert():    inputString = window.textEdit.toPlainText()    # 排除空串if( inputString == ""):        return    # 排除非法輸入的符號密度density = window.lineEdit.text()    try:        density = int(density)    except:        window.plainTextEdit.setPlainText("符號密度應該是數字! ")        return    # 正常執行outputString = ProString.convertString(inputString, density)    outputString = outputString.encode("utf-8").decode("unicode_escape")    window.plainTextEdit.setPlainText(outputString)if __name__ == "__main__" :    app = QApplication(sys.argv)    ui_file_name = "form.ui"    ui_file = QFile(ui_file_name)    if not ui_file.open(QIODevice.ReadOnly):        print("Cannot open {}: {}".format(ui_file_name, ui_file .errorString()))        sys.exit(-1)    loader = QUiLoader()    window = loader.load(ui_file)    ui_file.close()    if not window:        print(loader.errorString())        sys.exit(-1)    window.pushButton.clicked.connect( convert)    window.show()    sys.exit(app.exec_())

ProString.py

< code>import randomclass ProString:        '''Process string receive from user's interface class'''    @staticmethod    def convertString(string, density):        newString = ""        lengthOfStr = len(string)        for i in range(lengthOfStr):            randomUnicode = " "            for j in range(density):                randomUnicode += ("\\u03" + str(int(random.random() * 7)) + str([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'][int(random.random() * 16)]))            # 區分出字母、數字if('a' <= string[i] <= 'z' or 'A' <= string[i] <= 'Z' or '0' <= string[i] <= ' 9'):                part = string[i]            else:                part = str(string[i].

私信小編01即可獲取大量Python學習資料

文章為用戶上傳,僅供非商業瀏覽。發布者:Lomu,轉轉請註明出處: https://www.daogebangong.com/zh-Hant/articles/detail/fancy%20text%20generator.html

(810)
打賞 支付宝扫一扫 支付宝扫一扫
single-end

相關推薦