用 ImageMagick 製作行事曆
【摘要】本文敘述用 ImageMagick 和 BASH 指令製作陰曆行事曆的圖片,並將之固定在桌面當桌布。
【目錄】
【前言】【輸入檔】
【指令檔】
【貼在桌面】
【後語】
【前言】
一、一般月曆的第一天都是陽曆一號,再附上對照的陰曆。本例製作的月曆是用陰曆初一做開頭,以陽曆為對照。此外,還可以顯示簡單的記事、待辦事項之類的內容。
二、除了 BASH 和 ImageMagick 之外,還用到的程式有 Zenity 和 Linux 內建的 date
。
三、以下所提到的檔案都要放在同一個目錄裡。
四、一年前曾發表過「用ImageMagick 製作陰曆行事曆」,近日再度檢視修改,分享於此。
【輸入檔】
一、製作行事曆的原始資料當然是文字檔。本例特別採用 Linux 原有的 calendar
程式所規範的格式。如此一來,兩邊都可以用。
二、calendar
程式規定的格式是:
陽曆月(空格)陽曆日(跳格)說明
前兩欄是月和日(這當然是指陽曆日期),而且這兩欄要用空格(space)分開。接下來是跳格(tab)。其餘的內容都是該日的說明。也就是以第一個跳格為分界,左邊為日期,右邊是說明。
說明中可以再有跳格,但只做跳格用,沒有特別意義。
三、本例的格式是:
陽月(空格)陽日(跳格)陰月(跳格)陰日(跳格)假日(跳格)本月(跳格)記事
其中:
假日欄 是用來標示是否為假日;若是,用 0;若要上班上課,用 1。這是為了用不同的背景色。
本月欄 是為了用不同的字色(前景色)。本例所製作的月曆,每一週都是從週日開始,週六結束。所以第一週的前段可能是前一個月份的,而最後一週的後段可能是下個月份的。本月欄就是標出是否為當月;若是,用 1;若非,用 0。
四、此輸入檔可以有 #
開頭的註解和空白行。至於檔案的名稱,為了方便,也有一定格式:
陰曆年名-陰曆月份.txt
五、範例:庚子-2.txt
記事欄手動換行用 \\n
;目的是把字縮小,不然會使用能填滿整個記事欄的最大字;另外也可以調整位置。
#庚子年二月 2 23 2 1 0 1 2 24 2 2 1 1 2 25 2 3 1 1 2 26 2 4 1 1 2 27 2 5 1 1 2 28 2 6 0 1 \\n和平日 2 29 2 7 0 1 3 1 2 8 0 1 3 2 2 9 1 1 3 3 2 10 1 1 3 4 2 11 1 1 3 5 2 12 1 1 驚蟄 3 6 2 13 1 1 3 7 2 14 0 1 3 8 2 15 0 1 \\n婦女節 3 9 2 16 1 1 3 10 2 17 1 1 3 11 2 18 1 1 3 12 2 19 1 1 3 13 2 20 1 1 3 14 2 21 0 1 3 15 2 22 0 1 3 16 2 23 1 1 3 17 2 24 1 1 3 18 2 25 1 1 3 19 2 26 1 1 3 20 2 27 1 1 \\n春分 3 21 2 28 0 1 3 22 2 29 0 1 3 23 2 30 1 1 3 24 3 1 1 0 3 25 3 2 1 0 3 26 3 3 1 0 3 27 3 4 1 0 3 28 3 5 0 0
【指令檔】
此處以彩色版本為例。
#!/bin/bash # 製作陰曆行事曆 # 先確認年名 YearName # 輸入檔名稱格式:年名-陰曆月份.txt,如:庚子-3.txt # 如果是閏月,自行更名 # 輸入檔欄位:陽月、陽日、陰月、陰日、假日、本月、記事 # 假日:若是假日,用0;若非,用1 # 本月:前後月用0;當月用1 # 前後月要補滿整週 # 年名 YearName="庚子" # 詞語色;為了加粗,內外都用且同色 ColorWordFill="#0c0" ColorWordStroke="#0c0" # 月名欄背景色 ColorMonthBg="#ee6" # 月名字色 ColorMonth="#c0c" # 月名字體(可用字體見 convert -list font) FontMonth="AR-PL-UKai-TW" # 月名字體大小 PointMonth=28 # 月名欄尺寸 (月名欄寬=週名欄寬x7+框寬x12) SizeMonth="1062x40" # 月名欄框色 ColorMonthFrame="#880" # 月名欄框寬 BorderMonth=1 # 週名欄背景色 ColorWeekBg="#f84" # 週名字色 ColorWeek="#fff" # 週名字體 FontWeek="AR-PL-UKai-TW" # 週名字體大小 PointWeek=20 # 週名欄尺寸 (週名欄寬=陰曆日期欄寬+陽曆日期欄寬)(週名欄高=字體大小+8) SizeWeek="150x28" # 週名欄框色 ColorWeekFrame="#880" # 週名欄框寬 BorderWeek=1 # 陰曆日期字體 FontDayLunar="Noto-Sans-CJK-TC-Black" # 陽曆日期字體 FontDaySolar="Noto-Sans-CJK-TC-Bold" # 陰曆日期字體大小 PointDayLunar=24 # 陽曆日期字體大小 PointDaySolar=16 # 陰曆日期欄尺寸 (陰曆日期欄高=陽曆日期欄高) SizeDayLunar="54x24" # 陽曆日期欄尺寸 SizeDaySolar="96x24" # 日期欄框色 ColorDayFrame="#880" # 日期欄框寬 BorderDay=1 # 記事欄字體 FontNote="AR-PL-UMing-TW" # 記事欄字體大小用 +pointsize 取消,以便自動調整 # 記事欄尺寸 (記事欄寬=週名欄寬) SizeNote="150x64" # 月名欄只做當月的,但因為輸入檔可能有前後月的資料,所以必需知道月名欄是否做過 FlagMonth=0 # 計算所做的日數,每滿七天,就合成一週 CounterDay=1 # 計算一個月的週數 CounterWeek=1 # 以上是基本的設定值,以下開始製作 # 詢問欲製作的陰曆月份 MonthName=$(zenity --entry --title "輸入月份" --text "欲製作的陰曆月份(1..12)是:") # 若選[Cancel],即中斷程式 if [ -z ${MonthName} ] then exit fi # 輸入檔名稱;也檢查輸入的月份,若不合理,即中斷程式 if [ ${MonthName} -ge 1 -a ${MonthName} -le 12 ] then FileName="${YearName}-${MonthName}.txt" else exit fi # 詞語 convert -background ${ColorMonthBg} -fill ${ColorWordFill} -font ${FontMonth} -strokewidth 1 -stroke ${ColorWordStroke} -size ${SizeMonth} -gravity Center caption:"一年之計在於春 一日之計在於晨" -bordercolor ${ColorMonthFrame} -border ${BorderMonth} words.png # 週名欄;用 +append 選項橫向合併;因為是固定的,所以先做 convert -background ${ColorWeekBg} -fill ${ColorWeek} -font ${FontWeek} -pointsize ${PointWeek} -size ${SizeWeek} -gravity Center label:日 label:一 label:二 label:三 label:四 label:五 label:六 -bordercolor ${ColorWeekFrame} -border ${BorderWeek} +append weekname.png # 開始讀入資料,製作月曆的日與週 while read SolarMonth SolarDay LunarMonth LunarDay OnOff Current Event do # 略過#註解和空白行 if [ "${SolarMonth:0:1}" = "#" -o "${SolarMonth}" = "" ] then continue fi # 記事字色;非當月的字調暗 if [ ${Current} -eq 1 ] then ColorDay="#66f" ColorNote="#880" else ColorDay="#aaf" ColorNote="#aa0" fi # 月名欄 # 尋找陰曆日期為 1,且尙未做過月名欄 if [ ${LunarDay} -eq 1 -a ${FlagMonth} -eq 0 ] then convert -background ${ColorMonthBg} -fill ${ColorMonth} -font ${FontMonth} -pointsize ${PointMonth} -size ${SizeMonth} -gravity Center label:"${YearName}年 ${LunarMonth} 月" -bordercolor ${ColorMonthFrame} -border ${BorderMonth} monthname.png # 做過必需記錄,不然可能被改成下個月的 FlagMonth=1 # 輸出檔名要用,先存起來,不然也可能被改成下個月的 Month=${LunarMonth} fi # 一日 # 假日用不同底色 if [ ${OnOff} -eq 0 ] then ColorNoteBg="#fca" else ColorNoteBg="#ffc" fi # 今日日期用不同色(如果記事欄也用,會蓋過假日色) # 比較讀入的陽曆月日和系統的月日;相同時,改顏色;不然,沿用記事欄的顏色 if [ "${SolarMonth}/${SolarDay}" = "$(date +%-m/%-d)" ] then ColorDayBg="#f22" else ColorDayBg="#afa" fi # 一日 # (左上陰曆日)(右上陽曆月/日)用 +append 橫併,再與下方記事欄用 -append 縱併 convert -background ${ColorDayBg} -fill ${ColorDay} -font ${FontDayLunar} -pointsize ${PointDayLunar} -size ${SizeDayLunar} -gravity Center label:"${LunarDay}" -font ${FontDaySolar} -pointsize ${PointDaySolar} -size ${SizeDaySolar} -gravity East label:"${SolarMonth}/${SolarDay} " +append -background ${ColorNoteBg} -fill ${ColorNote} -font ${FontNote} +pointsize -size ${SizeNote} -gravity Center caption:"${Event}" -append day-${CounterDay}.png # 一週 (每七日用 +append 橫向合併) if [ ${CounterDay} -eq 7 ] then convert day-*.png -bordercolor ${ColorDayFrame} -border ${BorderDay} +append week-${CounterWeek}.png # 日計數歸零 CounterDay=0 # 週計數增1 (( CounterWeek += 1 )) fi # 日計數增1 (( CounterDay += 1 )) done < ${FileName} # 一個月 convert words.png monthname.png weekname.png week-*.png -append -bordercolor ${ColorMonthFrame} -border 3 ${YearName}-${Month}.png # 刪暫存檔 rm words.png monthname.png weekname.png week-*.png day-*.png exit
【貼在桌面】
因本例的系統是用 FluxBox 做視窗管理員,所以可以很輕易地將做出來的月曆圖片設為桌面背景圖片(桌布 wallpaper)。
fbsetbg -c 圖檔路徑
-c
:將圖片置中
【後語】
一、可以將此 BASH 檔設為可執行,以方便製作月曆。
二、當要修改行事曆時,先修改輸入檔,然後重做新的月曆。這些步驟可以再寫成一個簡單的 BASH 檔,並設為可執行。如果用習慣了,不用 5 秒就可以做出新的月曆並設為桌布。
三、只要稍加修改,即可做出陽曆的月曆,但是輸入檔就要大幅修改成以陽曆為主了。