本教程使用python3

推荐一个python基础教程


1.导入必要的模块

import numpy, random
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont

如果你没有安装这些模块

  • 使用pip安装:
pip3 install numpy
pip3 install matplotlib
pip3 install pillow
  • 或使用国内镜像:
pip3 install <包名> -i https://mirrors.aliyun.com/pypi/simple

2.定义一些常量

1.我们先定义一些必要的全局变量

H = 3   # 拼图高度
W = 3   # 拼图宽度
BG_COLOR = '#000000'   # 背景颜色(黑色)
mylist = []   # 
iswin = False   # 是否完成的标志
empty_xy = [W - 1, H - 1]   # 拼图中空格的坐标
my_img = Image.open('img.jpg')   # 打开图片
i_w, i_h = my_img.size   # 获取图片尺寸
i_w //= W   # 一格图片的宽
i_h //= H   # 一格图片的高

3.定义函数

def get_xyimg(img, x, y):
    '''
    获取图片的某一格
    :param img: 图片对象
    :param x: 这一个左上角像素坐标x
    :param y: 这一个左上角像素坐标y
    :return: 这一格的图片对象
    '''
    return img.crop((x * i_w, y * i_h, x * i_w + i_w, y * i_h + i_h))
def get_nimg(img, n):
    '''
    获取第n块图片
    :param img: 图片对象
    :param n: 第n块
    :return: 第n块图片对象
    '''
    return get_xyimg(img, n % W, n // W)
def get_img_bylist(img, list_):
    '''
    按照列表中的图片顺序中生成新的图片
    :param img: 图片对象
    :param list_: 其实就是全局变量my_list
    :return: 返回新合成的图片
    '''
    newimg = Image.new("RGB", (img.size[0] + W, img.size[1] + H), BG_COLOR)
    for n, i in enumerate(list_):
        newimg.paste(get_nimg(img, i), ((n % W) * (i_w + 1), (n // W) * (i_h + 1)))
    return newimg
def up_img(n):
    '''
    更新图片
    :param n: 鼠标所点击的图片的索引
    :return: 新的图片
    '''
    global mylist, empty_xy, iswin
    x, y = n % W, n // W
    empty_n = empty_xy[1] * W + empty_xy[0]
    if abs(x - empty_xy[0]) + abs(y - empty_xy[1]) == 1:
        mylist[empty_n], mylist[n] = mylist[n], mylist[empty_n]
        empty_xy = [x, y]
        for n, i in enumerate(mylist):
            if n != i:
                return get_img_bylist(my_img, mylist)
        iswin = True
        return get_img_bylist(my_img, mylist)
    return
def on_calck(event):
    '''
    发生鼠标点击事件后执行的函数
    :param event: 事件参数
    :return: 
    '''
    axtemp = event.inaxes
    print(f'点击了{event.xdata},{event.ydata}')
    calck_n = (event.ydata // i_h) * W + event.xdata // i_w
    print(f'点击了第{calck_n}张')
    new_img = up_img(int(calck_n))
    if new_img:
        if iswin:
            print('胜利')
            new_img = new_img.point(lambda p: p * 0.5)
            draw = ImageDraw.Draw(new_img)
            f_size = 80
            font = ImageFont.truetype("C:\Windows\Fonts\msyh.ttf", f_size, encoding="unic")  # 设置字体
            draw.text((W * i_w // 2 - f_size // 2 * 4, H * i_h // 2 - f_size // 2), "YOU WIN", (255, 0, 0), font=font)
        axtemp.imshow(
            numpy.array(
                new_img
            ),
            animated=True
        )
        figure.canvas.draw_idle()  # 绘图动作实时反映在图像上
def init():
    # 初始化
    global mylist, my_img
    mylist = list(range(W * H))   # 新建一个顺序列表
    random.shuffle(mylist)   #打乱
    # 将最后一块图片设为空
    if W * H - 1 != mylist[-1]:
        myindex = mylist.index(W * H - 1)
        mylist[myindex], mylist[-1] = mylist[-1], mylist[myindex]
    last_n = mylist[-1]
    my_img.paste(
        Image.new("RGB", (i_w, i_h), BG_COLOR),
        ((last_n % W) * i_w, (last_n // W) * i_h)
    )
    return get_img_bylist(my_img, mylist)
figure = plt.figure()
axes_image = plt.imshow(numpy.array(init()), animated=True)  # 把获取的图片话在坐标轴上面
figure.canvas.mpl_connect('button_press_event', on_calck)
plt.show()

4.最终效果

效果图

Last modification:July 2nd, 2020 at 04:46 pm
如果觉得我的文章对你有用,请随意赞赏