PIL画日历

前言

PIL = Python Image Library, 可以看出PIL是图像处理相关的库
官网介绍是通用图像处理工具, 如read/write, cutting/pasting/merging, rotate/resize等

The core image library is designed for fast access to data stored in a
few basic pixel formats. It should provide a solid foundation for a
general image processing tool.

相较于opencv2, PIL的确是更基础, 更易用

知识点

  • RGB通道
  • Image.paste, 2-tuple指定左上角, 4-tuple指定图片4角
  • ImageDraw.Draw(img), 画笔对象, 可以在图片上画图形, 文字等
  • ImageFont, 字体对象

效果图

PIL画日历

源码

from PIL import Image, ImageDraw, ImageFont
import calendar


def drawMonth(month=1):
    WEEK = ('MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN')
    MONTH = ('January', 'February', 'March', 'April', 'May', 'June',
             'July', 'August', 'September', 'October', 'November', 'December')

    # create new blank picture
    img = Image.new('RGB', size=(1920, 1080), color=(255,255,255))
    width, height = img.size
    # rows = 2 titles + 5 rows of days + 2(head + footer)blank
    # cols = 7 cols of week + 1 blank for left + 3 col for pic
    rows, cols = 9, len(WEEK) + 4
    colSpace, rowSpace = width // cols, height // rows

    # paste your img on the right, 549*1080
    bgImg = Image.open('cat1.jpg')
    bgWidth, _ = bgImg.size
    img.paste(bgImg, box=(width-bgWidth, 0))

    # define font and size
    month_font = r'C:\Windows\Fonts\BAUHS93.TTF'
    title_font = r'C:\Windows\Fonts\STCAIYUN.TTF'
    day_font = r'C:\Windows\Fonts\SitkaB.ttc'
    month_size, title_size, day_size = 80, 58, 34

    draw = ImageDraw.Draw(img)
    for i in range(len(WEEK) + 1):
        # draw month title
        if i == 0:
            draw.text((colSpace, rowSpace), MONTH[month-1], fill=(0,0,0,), font=ImageFont.truetype(month_font, size=month_size))
            top = rowSpace // 10
            draw.line(xy=[(colSpace, rowSpace*2-top * 2), (colSpace*7.5, rowSpace*2-top * 2)], fill=(0,0,0))
            draw.line(xy=[(colSpace, rowSpace * 2 - top * 1), (colSpace * 7.5, rowSpace * 2 - top * 1)], fill=(0, 0, 0))
            continue
        # draw week title
        draw.text((colSpace*i, rowSpace*2), WEEK[i-1], fill=(0,0,0), font=ImageFont.truetype(title_font, size=title_size))

    # draw days
    cal = calendar.Calendar(firstweekday=0)
    row, col = 3, 1
    for day in cal.itermonthdays(2019, month):
        if day > 0:
            # if weekday, draw with red color
            if col == 6 or col == 7:
                fill = (255, 0, 0)
            else:
                fill = (0, 0, 0)
            draw.text((colSpace * col + day_size, rowSpace * row), str(day), fill=fill, font=ImageFont.truetype(day_font, size=day_size))
        col += 1
        # to a new week
        if col == 8:
            col = 1
            row += 1

    img.save(MONTH[month-1] + '.png')

if __name__ == '__main__':
    drawMonth(month=4)