老板讓很快處理數(shù)百圖片,我該辭職嗎

文 |?太陽雪
來源:Python 技術(shù)「ID: pythonall」

工作種常常會遇到一些棘手的問題,干好了名利雙收,干不好就可能失去工作機(jī)會,特別是在疫情嚴(yán)重的現(xiàn)在,裁員壓力很大:(
從天而降
小派同學(xué),剛進(jìn)公司不久,接到了一個任務(wù),需要在立即將數(shù)百張圖片進(jìn)行縮放處理,并且加上水印,以便在網(wǎng)頁上展示,處理后的圖片像這樣:

正常處理一張照片,從打開、調(diào)整大小、加上文字,另存,需要將近一分鐘,幾百張圖片,手工操作,簡直是 Mission Impossible,這可如何是好,放棄呢還是硬著頭皮扛下來……
對于有 Python 技能的我們來說,這都不是事
神器入場
圖片處理,Pillow 首屈一指,它源自于 PIL(Python Imaging Library),是 Python 平臺事實上的圖像處理標(biāo)準(zhǔn)庫,功能非常強大,而且接口簡單。
為了支持 Python 3.x,在 PIL 的基礎(chǔ)上創(chuàng)建了兼容的版本,Pillow,并且加入了許多新特性,因此今天我們的主角是 Pillow,非常適合當(dāng)前的任務(wù)場景
通過 pip 安裝:
$ pip install pgmagick注意:Pillow 和 PIL 不能同時存在,如果已經(jīng)安裝過 PIL 請先卸載或者創(chuàng)建虛擬環(huán)境,再安裝 Pillow 創(chuàng)建虛擬環(huán)境,可參考 《Python 虛擬環(huán)境 看這一篇就夠了》
庖丁解牛
有了處理神器 pillow,現(xiàn)在來分析下任務(wù)
圖片是為了在 Web 上展示的,所以體積不能太大,另外要保持一定的清晰度 要處理的圖像文件格式有多種, png、jpg(jpeg)等,所以需要同時支持多種格式 對于處理后的圖片需要添加水印,所以需要用到 pillow 的繪制功能
縮放
直接上代碼:
from PIL import Imagedef resize(img, size):nsize = scale(img.size, size)return img.resize(nsize, Image.ANTIALIAS)def scale(size, lsize):nsize = (size[0], size[1])if nsize[0] > lsize[0]:nsize = (lsize[0], int(lsize[0]*nsize[1]/nsize[0]))if nsize[1] > lsize[1]:nsize = (int(lsize[1]*nsize[0]/nsize[1]), lsize[1])return nsize
定義 resize方法,接受一個圖片對象,和調(diào)整后的大?。╰urtle 類型)利用 Pillow Image 對象的 resize方法進(jìn)行縮放,第二個參數(shù)Image.ANTIALIAS作用是抗鋸齒,會讓調(diào)整后的圖像更清晰返回處理好的圖片對象,以便后續(xù)操作 scale方法用來計算調(diào)整后的圖像規(guī)格,利用等比縮放原理,原始圖像規(guī)格為 (x,y),調(diào)整后的為 (x',y'), 就會有:x/y = x'/y',所以給定三個值,就可以計算出第四個值
水印
圖片加水印有兩種方式:
一種是在圖片上加上可見的文字或者圖標(biāo),適合在網(wǎng)上展示,用于聲明圖片版權(quán)等
另一種是在圖像中,加入不可見數(shù)據(jù),用戶圖片的版權(quán)保護(hù)和防偽,也可以圖像簽名
因為圖片是為了在網(wǎng)上展示,所以用第一種加水印方式
原理是:創(chuàng)建一個和原圖大小一致的透明圖片,將水印文字寫到圖片的右下角,然后將水印圖片和原圖進(jìn)行疊加,成為加完水印的圖片
上代碼:
def waterMark(image, text, font=None):font = font if font else ImageFont.truetype(r"C:\Windows\Fonts\STHUPO.TTF", 24)mode = image.modeif mode != 'RGBA':rgba_image = image.convert('RGBA')else:rgba_image = imagetext_overlay = Image.new('RGBA', rgba_image.size, (255, 255, 255, 0))image_draw = ImageDraw.Draw(text_overlay)text_size_x, text_size_y = image_draw.textsize(text, font=font)# 設(shè)置文本文字位置text_xy = (rgba_image.size[0] - text_size_x - 10, rgba_image.size[1] - text_size_y - 10)# 設(shè)置文本顏色和透明度image_draw.text(text_xy, text, font=font, fill=(255, 255, 255, 100))image_with_text = Image.alpha_composite(rgba_image, text_overlay)if mode != image_with_text.mode:image_with_text = image_with_text.convert(mode)return image_with_text
waterMark是為圖片加水印的方法,參數(shù)分別是圖像對象,水印文字,和字體字體可以選擇系統(tǒng)中,字體文件夾中的字體文件,如果有漢字,需要選漢字字體文件,這里默認(rèn)使用 華文琥珀字體如果原始圖像不是 RGBA模式,將轉(zhuǎn)換為RGBA模式,即增加透明通道,以便水印圖片疊加按照原始圖片大小,創(chuàng)建一個透明通道值為 0,即全透明的圖片,作為水印圖層獲取圖層上的繪制接口 image_draw, 然后計算將要繪制水印文字的大小,繪制文字大小取決于字體、字號和文本長度計算出水印塊在原始圖片中右下角的坐標(biāo),且最小離邊距為 10 個像素 使用繪制接口,指定繪制坐標(biāo)、顏色和透明度,將水印繪制在水印圖層上 最后使用 pillow Image 類方法 alpha_composite將原始圖像和水印圖層合并判斷原始圖片模式是否于轉(zhuǎn)換后的相同,如果不同轉(zhuǎn)換為原始圖像模式
集成
有了縮放和水印功能,現(xiàn)在可以集成了
因為要處理多個圖片,需要有編寫一個方法,指定圖片目錄,獲取目錄中的圖片,做為處理的輸入
上代碼:
def process(imgPath, destPath=None, size=(800,600), text=""):destPath = destPath if destPath else os.path.join(imgPath,'out','')if not os.path.isdir(destPath):os.makedirs(destPath)files = [x for x in os.listdir(imgPath) if os.path.isfile(imgPath + x)]for f in files:fext = os.path.splitext(f)[1] # 擴(kuò)展名if fext in ['.png', '.jpg', '.bmp', '.jpeg']:img = Image.open(os.path.join(imgPath, f))img = resize(img, size)img = waterMark(img, text)img.save(os.path.join(destPath,f))
process是整體處理方法,參數(shù)分別是圖片目錄路徑,目標(biāo)路徑(處理完成后的存放位置),標(biāo)準(zhǔn)大小,以及水印文字如果沒有提供目標(biāo)路徑,默認(rèn)為圖片目錄中的 out目錄如果目標(biāo)位置不存在,則創(chuàng)建 利用 os.listdir獲取目錄中的文件名和目錄名,過濾掉非文件對象,匯總到集合files中遍歷 files,獲取擴(kuò)展名,過濾掉非圖片文件對圖片進(jìn)行處理,打開,調(diào)整尺寸,添加水印,最后保存到目標(biāo)目錄中
最后在是調(diào)用:
if __name__ == "__main__":process("D:\\images\\", text="@python技術(shù)")
精彩呈現(xiàn)
測試了 208 張桌面背景圖片,分辨率大體為 1920 X 1080,運行環(huán)境是 Win10,CUP i5-10210U,內(nèi)存 16GB,運行時間在 20秒左右

注意:不同環(huán)境中,運行時間會有所不同
這是待處理文件:

這是處理后的結(jié)果:

再看下水印效果:

好了,交工,感受到嘉獎的味道了嗎?
總結(jié)
工作中常常會遇到一些棘手的問題,與其說是阻礙或者挑戰(zhàn),倒不如說是一個機(jī)會,正是這樣一個個機(jī)會,成就了未來強大的我們。理想很豐滿,現(xiàn)實很骨感,只有擁有足夠的技能和綜合能力,才能抓住這些機(jī)會,祝愿明天的你更強大!
參考
https://www.liaoxuefeng.com/wiki/1016959663602400/1017785454949568 https://blog.csdn.net/ajian6/article/details/93615594 https://www.pythonf.cn/read/71 https://zhuanlan.zhihu.com/p/33450843
PS:公號內(nèi)回復(fù)「Python」即可進(jìn)入Python 新手學(xué)習(xí)交流群,一起 100 天計劃!
老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點一下,如果感覺文章內(nèi)容不錯的話,記得分享朋友圈讓更多的人知道!


【代碼獲取方式】
