聲明一下,以上圖片來源於網絡,網友公開發布的文章,如有侵權,請告知刪除。
接下來,我們就可以開工了。
目標:照片牆
於是我們今天的任務就比較明確了,做一個520形狀的照片牆。分析:算法實現
那麼很顯然,核心問題就是這個連續貼圖的問題。照片變成小方塊以後,貼到什麼位置,這其實是一個計算問題。
因為不同的數字之間的規律不統一,而且還可能用到心形這樣的形狀。所以直接採用數學的方法去找規律寫循環,可能不那麼理想化。
所以,教大家一種法法,你們盯著上面的圖片再看,看看能不能看到下面的東西。
沒錯,這就是我們會考經常考的點陣數位化嘛,不過是從文字遷移到圖片。雖然一行行寫起來繁瑣一點,但是,前面說了,費點心思嘛。
實現:遍歷貼圖
接下來就是無聊的編碼時間了。
1、生成背景圖
我先生成一個背景圖,上面是23*8的矩陣,每個小照片塊,我們用50*50的話,那我們要生成的背景大小就是1150*400。
from PIL import Image,ImageColor
color=ImageColor.getrgb('rgb(170,16,16)')img=Image.new("RGBA",(1150,400),color)img.save("bg.png")這個是用RGB顏色表示的方法,如果要簡化一些的話。直接color="pink"就可以生成粉色背景。好了,底色圖有了。
2、單圖寫入測試
千裡之行,始於足下,我們先往上面的背景裡寫一張圖試試,這些代碼直接百度一下Python貼圖或圖片合成即可,或者看PIL文檔。
from PIL import Image
bgImage=Image.open("bg.png")pstImage=Image.open("1.png")pi=pstImage.resize((50,50),Image.ANTIALIAS)bgImage.paste(pi,(50,50))bgImage.save("single.png")3、多圖寫入實現
有了前面的鋪墊,接下來,說簡單也就簡單了。讀取那個記事本文件,循環判斷是否貼圖即可。
讀記事本的代碼我們之前用過多次,回顧如下:
with open("data.txt","r") as f: lines=f.readlines() for line in lines: print(line.strip('\n'))於是就有了這個的代碼和效果。
from PIL import Image
bgImage=Image.open("bg.png")pstImage=Image.open("1.png")pi=pstImage.resize((50,50),Image.ANTIALIAS)r=0c=0with open("data.txt","r") as f: lines=f.readlines() for line in lines: for l in line.strip("\n"): if l=="1": bgImage.paste(pi,(50*c,50*r)) c=c+1 #行內挨個後移貼圖起點 c=0 #換行後列從0開始,為下一行貼圖準備 r=r+1 #換行後行號增1,為下一行貼圖準備bgImage.save("single.png")請注意看下注釋部分,決定了能否對應貼圖到位。
其實看到這裡,你可能忽然會覺得,那個數字矩陣,不就是個二維列表嗎?幹嘛非要存到txt呢,我在程序裡定義個二維列表不就完了?沒錯,是為了可擴展性,這樣你可以做多個形狀txt隨意調用且不容易丟失。
思考:圖源讀取
這裡有個比較重要的問題,就是如果你的圖片源不是四四方方的圖怎麼辦?其實這還隱藏著一個批量的圖片裁切處理問題。由於50*50的比例比較小,我們暫時忽略了resize後的變形問題,對於一些特殊比例的可能需要手工處理。
另外,我們準備足夠多的照片按什麼順序來讀取呢?一個比較合理有趣的方案是讀取照片的存儲時間,按時間先後來讀取。或者可以手工給圖片編號,按照編號依次讀取,這些就看你們的心思了。
收官:最終編碼
我們把記事本文件讀取跑一遍,算一下,一共需要75張照片,所以準備75張以上的圖片備用。
這裡低調一點,我就用百度圖片裡扒下來的風景照來生成最終照片牆。
最終代碼如下
from PIL import Image
bgImage=Image.open("bg.png")
r=0c=0n=0with open("data.txt","r") as f: lines=f.readlines() for line in lines: for l in line.strip("\n"): if l=="1": pstImage=Image.open(r"pictures/風景_"+str(n)+".jpg") n=n+1 pi=pstImage.resize((50,50),Image.ANTIALIAS) bgImage.paste(pi,(50*c,50*r)) c=c+1 c=0 r=r+1 bgImage.save("result.png")最終效果如下
修飾:添加文字
在圖片上寫文字,前面的文章也多有涉及,這裡就不喧賓奪主了。就是背景下面可以多預留一點空白,用於寫入一些浪漫的話。
後記:教學延拓
其實這個案例,作為教學上的案例的話,不僅僅局限於520,母親節、國慶節,其實都可以。圖案也不僅僅局限於以上圖案,只要學生能設計好圖案,生成txt數據都可以。案例知識點涵蓋文件讀寫、圖像處理、列表與循環、算法等等,希望對老師們教學有所啟發。也希望我們通過代碼,傳遞溫情。愛技術、愛專業的同時,更要好好愛家人、愛生活。連結: https://pan.baidu.com/s/11HR66OFbvqVm7eZ47pEAtg 提取碼: 7gkm