Python實(shí)現(xiàn)制作透明背景的電子印章
一、前言
今天分享一個(gè)Python 制作透明背景的電子印章的代碼,代碼是通過網(wǎng)絡(luò)獲得并整理的,大家可以參考和學(xué)習(xí)。
二、步驟解析
代碼我已調(diào)試過了,下面是操作步驟:
- 將代碼復(fù)制到你的py文件中,保存在本地C盤根目錄下,名為:seal.py
- 在運(yùn)行代碼時(shí),根據(jù)提示安裝相應(yīng)模塊
- 根據(jù)你的實(shí)際情況修改代碼中相應(yīng)參數(shù)
- Win+R運(yùn)行cmd,在命令行中輸入:python C:/seal.py回車查看結(jié)果
- 可以看到命令行中打印出相應(yīng)信息,等待圖片生成即可
至此,我們就完成了Python 制作透明背景的電子印章的程序執(zhí)行,大家喜歡的記得支持一下,有遇到問題的隨時(shí)找我溝通。
三、源代碼和運(yùn)行效果
1.源代碼
''' Python制作透明背景的電子印章 ''' # 導(dǎo)入包 from PIL import Image,ImageFont,ImageDraw, ImageFilter from math import pi, cos, sin, tan from random import randint # 定義方法 def is_Chinese(ch): '''判斷字符是否為中文''' if '\u4e00' <= ch <= '\u9fff': return True return False def pentagram(x, y, R, yDegree=0): ''' 計(jì)算五角星各個(gè)頂點(diǎn) int R:五角星的長軸 int x, y:五角星的中心點(diǎn) int yDegree:長軸與y軸的夾角 ''' rad = pi / 180 # 每度的弧度值 r = R * sin(18 * rad) / cos(36 * rad) # 五角星短軸的長度 # 求取外圈點(diǎn)坐標(biāo) RVertex = [(x - (R * cos((90 + k * 72 + yDegree) * rad)), y - (R * sin((90 + k * 72 + yDegree) * rad))) for k in range(5)] # 求取內(nèi)圈點(diǎn)坐標(biāo) rVertex = [(x - (r * cos((90 + 36 + k * 72 + yDegree) * rad)), y - (r * sin((90 + 36 + k * 72 + yDegree) * rad))) for k in range(5)] # 頂點(diǎn)左邊交叉合并 vertex = [x for y in zip(RVertex, rVertex) for x in y] return vertex def circle(x, y, r): '''計(jì)算圓的上下左右切點(diǎn)''' return (x - r, y - r, x + r, y + r) # 定義類 class Stamp: def __init__(self, edge = 5, # 圖片邊緣空白的距離 H = 160, # 圓心到中層文字下邊緣的距離 R = 250, # 圓半徑 border = 13, # 字到圓圈內(nèi)側(cè)的距離 r = 90, # 五星外接圓半徑 fill = (255, 0, 0, 120),# 印章顏色, 默認(rèn)純紅色, 透明度0-255,建議90-180 words_up = "", # 上部文字 angle_up = 270, # 上部文字弧形角度 font_size_up = 80, # 上部文字大小 font_xratio_up = 0.66, # 上部文字橫向變形比例 stroke_width_up = 2, # 上部文字粗細(xì),一般取值0,1,2,3 words_mid="", # 中部文字 angle_mid = 72, # 中部文字弧形角度 font_size_mid = 60, # 中部文字大小 font_xratio_mid = 0.7, # 中部文字橫向變形比例 stroke_width_mid=1, # 中部文字粗細(xì),一般取值0,1,2 words_down="",# 下部文字 angle_down = 60, # 下部文字弧形角度 font_size_down = 20, # 下部文字大小 font_xratio_down = 1, # 下部文字橫向變形比例 stroke_width_down=1, # 下部文字粗細(xì),一般取值0,1,2 img_wl_path = "", # 紋理圖路徑 save_path = "" # 保存圖片路徑 ): # 打開紋理圖像,隨機(jī)截取旋轉(zhuǎn) self.img_wl = Image.open(img_wl_path) # 圖像初始設(shè)置為None self.img = None self.save_path = save_path self.fill = fill # 印章顏色 self.edge = edge # 圖片邊緣空白的距離 self.H = H # 圓心到中層文字下邊緣的距離 self.R = R # 圓半徑 self.r = r # 五星外接圓半徑 self.border = border # 字到圓圈內(nèi)側(cè)的距離 self.words_up = words_up # 上部文字 self.angle_up = angle_up # 上部文字弧形角度 self.font_size_up = font_size_up # 上部文字大小 self.font_xratio_up = font_xratio_up # 上部文字橫向變形比例 self.stroke_width_up = stroke_width_up # 上部文字粗細(xì),一般取值0,1,2,3 self.words_mid = words_mid # 中部文字 self.angle_mid = angle_mid # 中部文字弧形角度 self.font_size_mid = font_size_mid # 中部文字大小 self.font_xratio_mid = font_xratio_mid # 中部文字橫向變形比例 self.stroke_width_mid = stroke_width_mid # 中部文字粗細(xì),一般取值0,1,2,3 self.words_down = words_down # 下部文字 self.angle_down = angle_down # 下部文字弧形角度 self.font_size_down = font_size_down # 下部文字大小 self.font_xratio_down = font_xratio_down # 下部文字橫向變形比例 self.stroke_width_down = stroke_width_down # 中部文字粗細(xì),一般取值0,1,2,3 def draw_rotated_text(self, image, angle, xy, r, word, fill, font_size, font_xratio, stroke_width, font_flip = False, *args, **kwargs): """ image:底層圖片 angle:旋轉(zhuǎn)角度 xy:旋轉(zhuǎn)中心 r:旋轉(zhuǎn)半徑 text:繪制的文字 fill:文字顏色 font_size:字體大小 font_xratio:x方向縮放比例(印章字體寬度較標(biāo)準(zhǔn)宋體偏窄) stroke_width: 文字筆畫粗細(xì) font_flip:文字是否垂直翻轉(zhuǎn)(印章下部文字與上部是相反的) """ # 加載字體文件-直接使用windows自帶字體,中文用simsun, 英文用arial if is_Chinese(word): font = ImageFont.truetype("C:/Windows/Fonts/simsun.ttc", font_size, encoding="utf-8") else: font = ImageFont.truetype("C:/Windows/Fonts/arial.ttf", font_size, encoding="utf-8") # 獲取底層圖片的size width, height = image.size max_dim = max(width, height) # 創(chuàng)建透明背景的文字層,大小4倍的底層圖片 mask_size = (max_dim * 2, max_dim * 2) # 印章通常使用較窄的字體,這里將繪制文字的圖層x方向壓縮到font_xratio的比例 mask_resize = (int(max_dim * 2 * font_xratio), max_dim * 2) mask = Image.new('L', mask_size, 0) # 在上面文字層的中心處寫字,字的左上角與中心對其 draw = ImageDraw.Draw(mask) # 獲取當(dāng)前設(shè)置字體的寬高 bd = draw.textbbox((max_dim, max_dim), word, font=font, align="center", *args, **kwargs) font_width = bd[2] - bd[0] font_hight = bd[3] - bd[1] # 文字在圓圈上下的方向,需要通過文字所在文字圖層的位置修正,保證所看到的文字不會(huì)上下顛倒 if font_flip: word_pos = (int(max_dim-font_width/2), max_dim+r-font_hight) else: word_pos = (int(max_dim-font_width/2), max_dim-r) # 寫字, 以xy為中心,r為半徑,文字上邊中點(diǎn)為圓周點(diǎn),繪制文字 draw.text(word_pos, word, 255, font=font, align="center", stroke_width = stroke_width, *args, **kwargs) # 調(diào)整角度,對于Π*n/2的角度,直接rotate即可,對于非Π*n/2的角度,需要先放大圖片以減少旋轉(zhuǎn)帶來的鋸齒 if angle % 90 == 0: rotated_mask = mask.resize(mask_resize).rotate(angle) else: bigger_mask = mask.resize((int(max_dim*8*font_xratio), max_dim*8), resample=Image.BICUBIC) rotated_mask = bigger_mask.rotate(angle).resize(mask_resize, resample=Image.LANCZOS) # 切割文字的圖片 mask_xy = (max_dim*font_xratio - xy[0], max_dim - xy[1]) b_box = mask_xy + (mask_xy[0] + width, mask_xy[1] + height) mask = rotated_mask.crop(b_box) # 粘貼到目標(biāo)圖片上 color_image = Image.new('RGBA', image.size, fill) image.paste(color_image, mask) def draw_stamp(self): #創(chuàng)建一張底圖,用來繪制文字 img = Image.new("RGBA",(2*(self.R+self.edge),2*(self.R+self.edge)),(255,255,255,0)) draw = ImageDraw.Draw(img) #繪制圓弧, R為外邊緣,width往圓心算 draw.arc(circle(self.R+self.edge, self.R+self.edge, self.R), start=0, end=360, fill=self.fill, width = self.border) #繪制多邊形 draw.polygon(pentagram(self.R+self.edge,self.R+self.edge,self.r), fill=self.fill, outline=self.fill) #繪制上圈文字 angle_word = self.angle_up / len(self.words_up) angle_word_curr = ((len(self.words_up)-1) / 2) * angle_word for word in self.words_up: self.draw_rotated_text(img, angle_word_curr, (self.R+self.edge,self.R+self.edge), self.R-self.border*2, word, self.fill, self.font_size_up, self.font_xratio_up, self.stroke_width_up) angle_word_curr = angle_word_curr - angle_word #繪制中層文字 angle_word = self.angle_mid / len(self.words_mid) angle_word_curr = -((len(self.words_mid)-1) / 2) * angle_word for word in self.words_mid: self.draw_rotated_text(img, 0, (self.R+self.edge+ self.H*tan(angle_word_curr*pi/180),self.R+self.edge), self.H, word, self.fill, self.font_size_mid, self.font_xratio_mid, self.stroke_width_mid, font_flip = True) angle_word_curr = angle_word_curr + angle_word #繪制下圈文字 angle_word = self.angle_down / len(self.words_down) angle_word_curr = -((len(self.words_down)-1) / 2) * angle_word for word in self.words_down: self.draw_rotated_text(img, angle_word_curr, (self.R+self.edge,self.R+self.edge), self.R-self.border*2, word, self.fill, self.font_size_down, self.font_xratio_down, self.stroke_width_down, font_flip = True) angle_word_curr = angle_word_curr + angle_word # 隨機(jī)圈一部分紋理圖 pos_random = (randint(0,200), randint(0,100)) box = (pos_random[0], pos_random[1], pos_random[0]+300, pos_random[1]+300) img_wl_random = self.img_wl.crop(box).rotate(randint(0,360)) # 重新設(shè)置im2的大小,并進(jìn)行一次高斯模糊 img_wl_random = img_wl_random.resize(img.size).convert('L').filter(ImageFilter.GaussianBlur(1)) # 將紋理圖的灰度映射到原圖的透明度,由于紋理圖片自帶灰度,映射后會(huì)有透明效果,所以fill的透明度不能太低 L, H = img.size for h in range(H): for l in range(L): dot = (l, h) img.putpixel(dot, img.getpixel(dot)[:3]+(int(img_wl_random.getpixel(dot)/255*img.getpixel(dot)[3]),)) # 進(jìn)行一次高斯模糊,提高真實(shí)度 self.img = img.filter(ImageFilter.GaussianBlur(0.6)) def show_stamp(self): if self.img: self.img.show() def save_stamp(self): if self.img: self.img.save(self.save_path) if __name__ == '__main__': # 上面的字 words_up = "小劉帶你學(xué)py技術(shù)社區(qū)" # 中間的字 words_mid="社區(qū)專用章" # 下面的字 words_down="2022092415" # 背景圖片路徑 img_wl_path = "D:\Back1.jpg" # 印章保存路徑 save_path = "D:\A\Project_1\stamp.png" # 執(zhí)行方法 stamp = Stamp(words_up=words_up,words_mid=words_mid,words_down=words_down,img_wl_path=img_wl_path,save_path=save_path) stamp.draw_stamp() stamp.show_stamp() stamp.save_stamp()
2.運(yùn)行效果圖
到此這篇關(guān)于Python實(shí)現(xiàn)制作透明背景的電子印章的文章就介紹到這了,更多相關(guān)Python印章內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python連接oracle數(shù)據(jù)庫操作實(shí)例及遇到的異常
這篇文章主要給大家介紹了關(guān)于python連接oracle數(shù)據(jù)庫操作實(shí)例及遇到的一些異常,Oracle是著名且廣泛使用的數(shù)據(jù)庫之一,而python的數(shù)據(jù)處理功能可以很好地利用這種連接性,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12完美處理python與anaconda環(huán)境變量的沖突問題
這篇文章主要介紹了完美處理Python與anaconda環(huán)境變量的沖突問題,對anaconda感興趣的同學(xué),可以參考下2021-04-04Python猜解網(wǎng)站數(shù)據(jù)庫管理員密碼的腳本
這篇文章主要和大家分享一個(gè)Python腳本,可以實(shí)現(xiàn)猜解網(wǎng)站數(shù)據(jù)庫管理員的密碼。文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下2022-02-02CoordConv實(shí)現(xiàn)卷積加上坐標(biāo)實(shí)例詳解
這篇文章主要介紹了CoordConv實(shí)現(xiàn)卷積加上坐標(biāo)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03使paramiko庫執(zhí)行命令時(shí)在給定的時(shí)間強(qiáng)制退出功能的實(shí)現(xiàn)
這篇文章主要介紹了使paramiko庫執(zhí)行命令時(shí),在給定的時(shí)間強(qiáng)制退出,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03error?conda:ProxyError:Conda?cannot?proceed?due?to?an?
這篇文章主要為大家介紹了error conda:ProxyError:Conda cannot proceed due to an error in your proxy configuration解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07python實(shí)現(xiàn)二級(jí)登陸菜單及安裝過程
這篇文章主要介紹了python實(shí)現(xiàn)二級(jí)登陸菜單及安裝過程,,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06python logging設(shè)置level失敗的解決方法
今天小編就為大家分享一篇python logging設(shè)置level失敗的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02