本项目在GitHub上的地址是:https://github.com/xuanqingdaoren/keepweizao
对应的视频请到我主页查看目前有两个视频:
关于keep跑步伪造软件的bug修改和更新_哔哩哔哩_bilibili
先放一张效果图:

由于我们学院只需要以此向上传跑步记录次数的截图,故我们不需要对GPS进行修改,而只需要对截图进行修改就行。于是我利用python进行生成随机数,然后利用PIL直接修改图片进行生成就行。
我们可以先截取头部图片:

然后截取一小段记录图片:

对记录图片进行修改然后进行日期排序就行,在这里修改代码如下:
img = Image.open('back.jpg')
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('msyh.ttc', size=34)
text = "{}月{}日".format(month,i)
draw.rectangle((46, 50, 178, 83), fill='white')
draw.text((46, 50), text, font=font, fill=(105, 105, 105))
text2 = "户外跑步{} 公里".format(distance_get)
font2 = ImageFont.truetype('msyh.ttc', size=40)
draw.rectangle((169, 172, 512, 210), fill='white')
draw.text((169, 172), text2, font=font2, fill=(35, 35, 35))
text3 = "用时 {} 配速 {}".format(time_get, pace_get)
font = ImageFont.truetype('msyh.ttc', size=34)
draw.rectangle((170, 247, 589, 275), fill='white')
draw.text((170, 242), text3, font=font, fill=(74, 74, 74))
text4 = random_time
font = ImageFont.truetype('msyh.ttc', size=36)
draw.rectangle((938, 209, 1030, 238), fill='white')
draw.text((938, 209), text4, font=font, fill=(152, 152, 152))
img.save('./3月/{}.jpg'.format(i)) 具体代码我分为了两个文件,首先是生成随机数的test.py
import random
def generate_run_stats(pace_min, pace_max, distance_min, distance_max):
# 设置配速和路程的区间
# pace_min, pace_max = 5, 7 # 配速区间(分钟/公里)
# distance_min, distance_max = 0.8, 1.2 # 路程区间(公里)
# 随机生成配速和路程
random_pace = random.uniform(pace_min, pace_max)
random_distance = random.uniform(distance_min, distance_max)
# 计算所需时间(配速乘以路程)
time_needed = random_pace * random_distance
minutes1 = int(random_pace)
seconds1 = round((random_pace - minutes1) * 60)
# 使用字符串格式化来确保秒数是两位数
seconds_str1 = f"{seconds1:02d}"
# 拼接成时间格式
time_str1 = '0' + str(minutes1) + "'" + str(seconds_str1) + '"'
# 返回配速、路程和所需时间
return time_str1, random_distance, time_needed
# 调用函数并输出结果
def convert_pace_to_time_format(pace_in_minutes_per_km):
# 分离整数部分和小数部分
minutes = int(pace_in_minutes_per_km)
seconds = round((pace_in_minutes_per_km - minutes) * 60)
if minutes < 10:
minutes = "00:0" + str(minutes)
elif 10 = 60:
hours = minutes // 60
if hours < 10:
minutes = "0" + str(hours) + ":" + str(minutes - hours * 60)
elif hours >= 10:
minutes = str(hours) + ":" + str(minutes - hours * 60)
# 使用字符串格式化来确保秒数是两位数
seconds_str = f"{seconds:02d}"
# 拼接成时间格式
time_str = f"{minutes}:{seconds_str}"
return time_str
def generate_random_time_between_22_and_23():
# 生成0到59之间的随机分钟数
random_minutes = random.randint(0, 59)
random_hours = random.randint(6, 23)
# 格式化时间为24小时制字符串
random_time = f"{random_hours}:{random_minutes:02d}"
return random_time
# 生成并打印随机时间
然后是运行文件main.py:
import os
import random
import re
import shutil
import tkinter as tk
from tkinter import *
from tkinter import filedialog
from PIL import ImageFont, ImageDraw, Image
import test
def save_image():
filepath = filedialog.asksaveasfilename(defaultextension='.jpg', filetypes=[("JPEG files", "*.jpg")])
if filepath:
try:
img = Image.open('combined_image.jpg') # 打开之前生成的图片
img.save(filepath) # 保存到用户指定的位置
print(f"Image saved to: {filepath}")
except Exception as e:
print(f"Error saving image: {e}")
# 窗口主函数
def create_window():
root = tk.Tk()
root.title("Input Window")
# 创建变量来保存输入框的内容
month_var = tk.StringVar()
num_suiji_var = tk.StringVar()
pace_min_var = tk.StringVar()
pace_max_var = tk.StringVar()
distance_min_var = tk.StringVar()
distance_max_var = tk.StringVar()
# 创建输入框
entries = [
(tk.Entry(root, textvariable=month_var), "月份,输入整数"),
(tk.Entry(root, textvariable=num_suiji_var), "次数,输入整数,2月次数不超28,其余月份次数不超过30或31"),
(tk.Entry(root, textvariable=pace_min_var), "配速最小值,输入整数(分钟/公里)"),
(tk.Entry(root, textvariable=pace_max_var), "配速最大值,输入整数(分钟/公里)"),
(tk.Entry(root, textvariable=distance_min_var), "路程最小值,输入整数(公里)"),
(tk.Entry(root, textvariable=distance_max_var), "路程最大值,输入整数(公里)")
]
# 布局输入框
for i, (entry, label) in enumerate(entries):
entry.grid(row=i, column=0)
tk.Label(root, text=label).grid(row=i, column=1)
# 创建处理按钮
tk.Button(root, text="Process", command=lambda: main(
month_var.get(), num_suiji_var.get(), pace_min_var.get(), pace_max_var.get(), distance_min_var.get(),
distance_max_var.get()
)).grid(row=6, column=0, columnspan=2)
# 创建另存为按钮
tk.Button(root, text="Save Image", command=save_image).grid(row=7, column=0, columnspan=2)
root.mainloop()
def main(month, num_suiji, pace_min, pace_max, distance_min, distance_max):
os.makedirs('3月')
# 生成1到28之间的15个不重复的随机数
if month == "2":
random_numbers = random.sample(range(1, 29), int(num_suiji))
elif month == "1" or "3" or "5" or "7" or "8" or "10" or "12":
random_numbers = random.sample(range(1, 32), int(num_suiji))
else:
random_numbers = random.sample(range(1, 30), int(num_suiji))
# 对生成的随机数进行排序
sorted_numbers = sorted(random_numbers)
for i in sorted_numbers:
pace, distance, time = test.generate_run_stats(int(pace_min), int(pace_max), float(distance_min),
float(distance_max))
pace_get = pace
distance_get = str(distance)[:4]
time1 = test.convert_pace_to_time_format(time)
time_get = time1
random_time = test.generate_random_time_between_22_and_23()
img = Image.open('back.jpg')
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('msyh.ttc', size=34)
text = "{}月{}日".format(month, i)
draw.rectangle((46, 50, 178, 83), fill='white')
draw.text((46, 50), text, font=font, fill=(105, 105, 105))
text2 = "户外跑步{} 公里".format(distance_get)
font2 = ImageFont.truetype('msyh.ttc', size=40)
draw.rectangle((169, 172, 512, 210), fill='white')
draw.text((169, 172), text2, font=font2, fill=(35, 35, 35))
text3 = "用时 {} 配速 {}".format(time_get, pace_get)
font = ImageFont.truetype('msyh.ttc', size=34)
draw.rectangle((170, 247, 589, 275), fill='white')
draw.text((170, 242), text3, font=font, fill=(74, 74, 74))
text4 = random_time
font = ImageFont.truetype('msyh.ttc', size=36)
draw.rectangle((938, 209, 1030, 238), fill='white')
draw.text((938, 209), text4, font=font, fill=(152, 152, 152))
img.save('./3月/{}.jpg'.format(i))
# 设置图片所在的文件夹路径
image_dir = '3月' # 替换为你的图片文件夹路径
shutil.copyfile('100.jpg', '3月/100.jpg')
# 获取文件夹中所有的图片文件名
image_files = [f for f in os.listdir(image_dir) if f.endswith('.jpg')]
# 使用正则表达式提取文件名中的数字,并根据数字对文件名进行排序
image_files.sort(key=lambda x: int(re.search(r'\d+', x).group()), reverse=True)
# 初始化一个空白图像,宽度为最宽图片的宽度,高度为所有图片高度之和
widths, heights = zip(*(Image.open(os.path.join(image_dir, f)).size for f in image_files))
max_width = max(widths)
total_height = sum(heights)
# 创建一个新的空白图像,用于拼接所有图片
new_img = Image.new('RGB', (max_width, total_height))
# 初始化y坐标(从上到下拼接)
y_offset = 0
# 遍历排序后的图片文件,将它们拼接到新图像上
for img_file in image_files:
img_path = os.path.join(image_dir, img_file)
with Image.open(img_path) as img:
# 将图片粘贴到新图像的指定位置
new_img.paste(img, (0, y_offset))
# 更新y坐标,以便下一张图片可以紧接着上一张图片粘贴
y_offset += img.height
# 保存拼接后的图像
new_img.save('combined_image.jpg')
shutil.rmtree('3月')
message = '图片创建成功,请点击Save Image获取'
tk.messagebox.showinfo(title='提示', message=message)
# 运行窗口主函数
create_window()