import calendar from datetime import datetime, timedelta from PIL import Image, ImageDraw, ImageFont, ImageOps from .data_proc import * import random filepath = os.path.dirname(__file__).replace("\\", "/") async def draw_calendar_grid_image(uid, year, month): # 获取该月的第一天是星期几,以及这个月有多少天 first_weekday, num_days = calendar.monthrange(year, month) # 调整第一天的索引,使周日对应0,周六对应6 first_weekday = (first_weekday + 1) % 7 # 设置单元格尺寸和内边距 cell_size = 50 cell_padding = 5 # 计算当前月份的行数 num_rows = (num_days + first_weekday + 6) // 7 + 1 # +1 行用于留空 # 计算图片宽度和高度 image_width = 7 * (cell_size + cell_padding) - cell_padding image_height = num_rows * (cell_size + cell_padding) - cell_padding # 创建图像对象 img = Image.new("RGBA", (image_width, image_height), "white") draw = ImageDraw.Draw(img) font_path = filepath + "/font/SourceHanSansCN-Medium.otf" print(font_path) font_normal = ImageFont.truetype(font=font_path, size=18) font_large = ImageFont.truetype(font=font_path, size=24) # 绘制网格线 for i in range(7): x = i * (cell_size + cell_padding) draw.line([(x, 55), (x, image_height)], fill="black", width=1) for j in range(0, image_height + cell_size, cell_size + cell_padding): draw.line([(0, j), (image_width, j)], fill="black", width=1) # 小🦌 deer_pipe_path = filepath + "/img/deer_pipe/deer_pipe.jpg" deer_pipe_img = Image.open(deer_pipe_path) deer_pipe_img = deer_pipe_img.resize((54, 50)) # 画标题 title = f"{month}月打卡记鹿" text_length = draw.textlength(text=title, font=font_large) img_xy = (int(((image_width - text_length + 55) / 2) - 55), 5) title_pos = ((image_width - text_length + 55) / 2, 10) img.paste(deer_pipe_img, img_xy) draw.text(title_pos, title, fill="black", font=font_large) # 获取🦌信息 days = await get_records(uid) # 填充日期 date = datetime(year, month, 1) for day in range(1, num_days + 1): weekday = (first_weekday + day - 1) % 7 row = (first_weekday + day - 1) // 7 + 1 # +1 行用于留空 x = weekday * (cell_size + cell_padding) + cell_padding y = row * (cell_size + cell_padding) + cell_padding img.paste(deer_pipe_img, (x - 4, y)) draw.text((x+20, y - 2), f"{str(day)}", fill="black", font=font_normal) if day in days: im = get_random_right() img = image_paste(im, img, (x - 4, y)) # 保存图片 # img.save(output_image_path) # 显示图片 # img.show() img = ImageOps.expand(img, border=5, fill="black") img = ImageOps.expand(img, border=5, fill="white") return img # 全局变量,用于存储已经选择过的文件名 selected_images = [] def get_random_right(): global selected_images path = filepath + "/img/deer_pipe/right" # 过滤掉已经选择过的文件名 im_name = [name for name in os.listdir(path) if name not in selected_images] # 如果所有文件都已经选择过,重新初始化已选择列表 if not im_name: selected_images = [] im_name = os.listdir(path) index = random.randint(0, len(im_name) - 1) im = im_name[index] selected_images.append(im) # 将选择的文件名添加到已选择列表中 im_path = os.path.join(path, im) im_file = Image.open(im_path) im_file = im_file.resize((50, 50)) return im_file # 图片粘贴 def image_paste(paste_image, under_image, pos): """ :param paste_image: 需要粘贴的图片 :param under_image: 底图 :param pos: 位置(x,y)坐标 :return: 返回图片 """ # 获取需要贴入图片的透明通道 r, g, b, alpha = paste_image.split() # 粘贴时将alpha值传递至mask属性 under_image.paste(paste_image, pos, alpha) return under_image