diff --git a/create_image.py b/create_image.py index f58b152..dd1546d 100644 --- a/create_image.py +++ b/create_image.py @@ -29,48 +29,44 @@ def create_background(input: bytes, width: int, height: int): def draw_text_with_shadow(image: Image.Image, text: str, - posx: int, - posy: int, - font): + posx: int | float, + posy: int | float, + font: ImageFont.ImageFont | ImageFont.FreeTypeFont): draw = ImageDraw.Draw(image) draw.text((posx + 2, posy + 2), text, font=font, fill='black') draw.text((posx, posy), text, font=font, fill='white') def draw_motd_text_with_shadow(image: Image.Image, text: str, - posx: int, - posy: int, - font): + posx: int | float, + posy: int | float, + font: ImageFont.ImageFont | ImageFont.FreeTypeFont): draw = ImageDraw.Draw(image) - w1, _, w2, _ = draw.textbbox((0, 0), text.strip(), font=font) - weight = w2 - w1 - motd_list = foramt_motd(text.strip(), weight) + motd_list = foramt_motd(text.strip(), draw, font) for pos, color, text in motd_list: - w1, _, w2, _ = draw.textbbox((0, 0), text, font=font) - weight = w2 - w1 - draw.text((posx + pos + 1 - weight, posy + 1), text, font=font, fill='black') - draw.text((posx + pos - weight, posy), text, font=font, fill=getrgb(color)) + draw.text((posx + pos + 1, posy + 1), text, font=font, fill='black') + draw.text((posx + pos, posy), text, font=font, fill=getrgb(color)) def create_image(background: bytes, icon: str | None, text_list: list[str], motd_list: list[str], font_url: str | None, - image_size: list[int] = [0, 0]): + image_size: tuple[int, int] = (0, 0)): # 图片尺寸 - if image_size == [0, 0] or image_size == []: + if type(image_size) != type(tuple()) or len(image_size) != 2: + assert ValueError("image_size is invalid") + + if image_size[0] == 0 and image_size[1] == 0: width = 1200 height = 400 - elif len(image_size) == 2: + else: width = image_size[0] height = image_size[1] - else: - assert ValueError("image_size is invalid") if (len(text_list) + len(motd_list)) * 20 + 20 > height: height = (len(text_list) + len(motd_list)) * 20 + 20 - else: - font_size = height // 12 + font_size = height // 12 if font_size * 20 > width - width // 2.5: font_size = (width - width // 2.5) // 20 @@ -92,7 +88,7 @@ def create_image(background: bytes, small_image = Image.open(BytesIO(icon)).resize((small_size, small_size), Image.Resampling.LANCZOS) - image.paste(small_image, (30, height // 2 - small_size // 2)) + image.paste(small_image, (int(width / 3 - small_size), int(height / 2 - small_size / 2))) # 设置字体 if font_url == None: @@ -106,13 +102,13 @@ def create_image(background: bytes, for i in range(motd_list_size): draw_motd_text_with_shadow(image, motd_list[i], - width // 2.5, + width / 2.5, start_posy + font_size * 1.2 * i, font) for i in range(text_list_size): draw_text_with_shadow(image, text_list[i], - width // 2.5, + width / 2.5, start_posy + font_size * 1.2 * (i + motd_list_size), font) diff --git a/motd_formatter.py b/motd_formatter.py index 9ba2aab..9ebfe49 100644 --- a/motd_formatter.py +++ b/motd_formatter.py @@ -1,3 +1,5 @@ +from PIL import ImageDraw, ImageFont + def format_color(color_code: str) -> str: """ 将Minecraft颜色代码转换为对应的颜色名称 @@ -30,7 +32,10 @@ def format_color(color_code: str) -> str: } return color_map.get(color_code.lower(), 'white') -def foramt_motd(data: str, weight: int) -> list[tuple[int, str, str]]: +def foramt_motd(data: str, + draw: ImageDraw.ImageDraw, + font: ImageFont.ImageFont | ImageFont.FreeTypeFont + ) -> list[tuple[int, str, str]]: """ 格式化 MOTD 文本,去除多余的空格和换行符 @@ -41,23 +46,25 @@ def foramt_motd(data: str, weight: int) -> list[tuple[int, str, str]]: list: 格式化后的 MOTD 文本 """ iter = 0 - character_count = 0 motd_list = [] color_state = "#FFFFFF" data_size = len(data) + weight_count = 0 while iter < data_size: if data[iter] == "§": if iter + 1 < data_size: color = data[iter + 1] text = "" iter += 2 - character_count += 1 while iter < data_size and data[iter] != "§" and data[iter] != "\n": text += data[iter] iter += 1 if color != "l": color_state = format_color(color) - motd_list.append(((iter - character_count * 2) / data_size * weight, color_state, text)) + w1, _, w2, _ = draw.textbbox((0, 0), text, font=font) + seg_weight = w2 - w1 + motd_list.append((weight_count, color_state, text)) + weight_count += seg_weight else: iter += 1 else: @@ -65,5 +72,8 @@ def foramt_motd(data: str, weight: int) -> list[tuple[int, str, str]]: while iter < data_size and data[iter] != "§" and data[iter] != "\n": text += data[iter] iter += 1 - motd_list.append(((iter - character_count * 2) / data_size * weight, "white", text)) + w1, _, w2, _ = draw.textbbox((0, 0), text, font=font) + seg_weight = w2 - w1 + motd_list.append((weight_count, "#FFFFFF", text)) + weight_count += seg_weight return motd_list