背景需求:
在实际操作中,孩子们把数字当做了自己的学好,这个提示老师可以给每位孩子做一份"学号数感训练
用AI反复写了很久的代码,终于实现了需求。
python
'''
数感训练-学号1-31,指定数字至少出现10次,学号数字,左上角有灰色的答案
AI对话大师,阿夏
2024年5月22日
'''
import random
import math
from PIL import Image, ImageDraw, ImageFont
from collections import Counter
import os
# 指定数字至少出现几次15-20之间
cs = 15
cs2 = 20
start=1
end=31
# 班级没有1号和7号(转学了)
numbers = [i for i in range(start, end+1) if i not in [1, 7]]
# numbers = [i for i in range(start,end+1) ]
print(numbers)
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\数字数感训练'
input_folder=path+r'\jpg'
os.makedirs(input_folder,exist_ok=True)
# 创建画布
canvas_width, canvas_height = 3000, 4000
canvas = Image.new('RGB', (canvas_width, canvas_height), (255, 255, 255))
draw = ImageDraw.Draw(canvas)
# 绘制黑色方框
border_color = (0, 0, 0)
border_width = 10
gray_color = (200, 200, 200)
# 定义左上角数字方框的边界坐标
x1, y1, x2, y2 = 0, 0, 700, 700
draw.rectangle([(x1, y1), (x2, y2)], outline=border_color, width=border_width)
# 定义学号数字方框的边界坐标
x1, y1, x2, y2 = 700, 0, 1000, 700
draw.rectangle([(x1, y1), (x2, y2)], outline=border_color, width=border_width)
# 定义答案方框的边界坐标
x1, y1, x2, y2 = 700, 0, 1000, 350
draw.rectangle([(x1, y1), (x2, y2)], outline=border_color, width=border_width,)
x1, y1, x2, y2 = 700, 350, 1000, 700
draw.rectangle([(x1, y1), (x2, y2)], outline=border_color, width=border_width,fill=gray_color)
n = 10
nn = []
for i in numbers:
while True:
numbers_written = [] # 存储成功绘制的圆圈内的数字
# 创建白色画布
canvas_color = (255, 255, 255)
canvas_inner = Image.new('RGB', (canvas_width, canvas_height), canvas_color)
draw_inner = ImageDraw.Draw(canvas_inner)
# 将黑色方框复制到白色画布中
canvas_inner.paste(canvas, (0, 0))
# 在左上角绘制数字
text_color = (0, 0, 0)
font_path = r"C:\Windows\Fonts\simhei.ttf" # 黑体字体路径,请根据实际情况修改
font_size = 500
font = ImageFont.truetype(font_path, font_size)
if len(str(i))==1:
draw_inner.text((230, 100), f'{i}', font=font, fill=text_color)
else:
draw_inner.text((90, 100), f'{i}', font=font, fill=text_color)
# 生成10磅黑线白色圆圈
circle_radius = 50
circle_border_color = (0, 0, 0)
circle_fill_color = (255, 255, 255)
border_width = 5
circle_distance = 60 + circle_radius * 2 # 圆圈之间的距离
bj = 30 # 圆形与边框的距离
# 存储圆圈的位置信息,用于检查是否相交
circle_positions = []
# 阿拉伯数字字体设置
number_font_size = 80
number_font = ImageFont.truetype(font_path, number_font_size)
circle_positions = []
numbers_written = []
for _ in range(5000):
# 生成圆心位置
x = random.randint(circle_radius + border_width + bj, canvas_width - circle_radius - border_width - bj)
y = random.randint(circle_radius + border_width + bj, canvas_height - circle_radius - border_width - bj)
# 排除左上角区域
if x <= 1100 and y <= 800:
continue
# 检查与已有圆圈是否相交
is_intersect = False
for position in circle_positions:
distance = math.sqrt((x - position[0]) ** 2 + (y - position[1]) ** 2)
if distance < circle_distance:
is_intersect = True
break
if not is_intersect:
# 绘制外圆,边线粗细为10磅
outer_circle_radius = circle_radius + border_width
outer_circle_bbox = (
x - outer_circle_radius, y - outer_circle_radius, x + outer_circle_radius, y + outer_circle_radius)
draw_inner.ellipse(outer_circle_bbox, outline=circle_border_color, width=border_width)
# 绘制内圆,填充为白色
inner_circle_radius = circle_radius
inner_circle_bbox = (
x - inner_circle_radius, y - inner_circle_radius, x + inner_circle_radius, y + inner_circle_radius)
draw_inner.ellipse(inner_circle_bbox, fill=circle_fill_color)
# 在圆圈内绘制随机生成的阿拉伯数字
number = random.choice(numbers)
number_width, number_height = draw_inner.textsize(str(number), font=number_font)
number_x = x - number_width // 2
number_y = y - number_height // 2
draw_inner.text((number_x, number_y), str(number), font=number_font, fill=(0, 0, 0))
# 将圆圈位置添加至列表
circle_positions.append((x, y))
numbers_written.append(number)
number_counts = Counter(numbers_written)
count_10 = number_counts[i]
print("实际生成的圆圈数量:", len(circle_positions))
print("生成圆圈中的数字:", numbers_written)
print("每种数字的数量:", number_counts)
print(f"数字 {i} 的数量:", count_10)
# 绘制数字 count_10
# 在左上角绘制数字
text_color = (0, 0, 0)
font_path = r"C:\Windows\Fonts\simhei.ttf" # 黑体字体路径,请根据实际情况修改
font_size = 180
font = ImageFont.truetype(font_path, font_size)
if len(str(count_10))==1:
draw_inner.text((800, 430), f'{count_10}', font=font, fill=text_color)
else:
draw_inner.text((760, 430), f'{count_10}', font=font, fill=text_color)
if count_10 >= cs and count_10 <=cs2:
# 保存为1.png
image_path = input_folder + fr'\{i:02d}.png'
canvas_inner.save(image_path)
n += 1
break
else:
print(f"数字 {i} 的数量小于 {cs} 次,重新生成圆圈。")
# 删除未保存的图片
image_path = input_folder + fr'\{i:02d}.png'
if os.path.exists(image_path):
os.remove(image_path)
continue
# 合并
import os
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from PyPDF2 import PdfWriter, PdfFileMerger
from PIL import Image
import img2pdf
def convert_images_to_pdf(image_folder, output_path):
pdf_merger = PdfFileMerger()
for image_file in os.listdir(image_folder):
if image_file.endswith('.jpg') or image_file.endswith('.png'):
image_path = os.path.join(image_folder, image_file)
pdf_path = os.path.splitext(image_path)[0] + '.pdf'
# 使用reportlab库将图片转换为单个PDF文件
c = canvas.Canvas(pdf_path, pagesize=letter)
c.drawImage(image_path, 0, 0, width=letter[0], height=letter[1])
c.save()
# 使用img2pdf库将图片转换为单个PDF文件
# with open(pdf_path, "wb") as pdf_file, open(image_path, "rb") as image_file:
# pdf_file.write(img2pdf.convert(image_file))
# 将单个PDF文件添加到PDF合并器中
pdf_merger.append(pdf_path)
# 合并所有单个PDF文件为一个最终的PDF文件
with open(output_path, 'wb') as output_file:
pdf_merger.write(output_file)
print(f"PDF文件已生成:{output_path}")
# 使用示例
image_folder = input_folder # 替换为你的图片文件夹路径
output_path = path + fr'\学号数感训练(学号{start}-{end}出现次数{cs}-{cs2})次.pdf' # 替换为你的输出PDF文件路径
convert_images_to_pdf(image_folder, output_path)
import shutil
os.shutil(input_folder)
运行时间长,因为随机抽取数量,不可能马上出现15个。这一份生成了25分钟才获得。
、