首页 > 编程语言 >python: draw

python: draw

时间:2023-06-19 23:22:43浏览次数:45  
标签:draw python self 0x00 pygame size rect brush

 

# -*- coding: utf-8 -*-
# pip install pygame
"""
DrawTool.py
画板

"""
import math
import pygame
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE, MOUSEBUTTONDOWN, MOUSEMOTION, MOUSEBUTTONUP  # 导入事件

class Brush(object):
    """
    画笔类
    """
    def __init__(self, screen):
        self.screen = screen  # 屏幕对象
        self.color = (0, 0, 0)  # 颜色
        self.size = 1  # 大小
        self.drawing = False  # 是否绘画
        self.last_pos = None  # 鼠标滑过最后的位置
        self.space = 1
        self.brush = pygame.image.load("img/pen.png").convert_alpha()  # 画笔图片
        self.brush_now = self.brush.subsurface((0, 0), (1, 1))  # 初始化画笔对象

    # 开始绘画
    def start_draw(self, pos):
        self.drawing = True
        self.last_pos = pos # 记录鼠标最后位置

    # 结束绘画
    def end_draw(self):
        self.drawing = False

    # 获取当前使用画笔
    def get_current_brush(self):
        return self.brush_now # 获取当前使用的画笔对象

    def set_size(self, size):  # 设置画笔大小
        if size < 0.5: # 判断画笔尺寸小于0.5
            size = 0.5 # 设置画笔最小尺寸为0.5
        elif size > 32: # 判断画笔尺寸大于32
            size = 32 # 设置画笔最大尺寸为32
        self.size = size # 设置画笔尺寸
        # 生成画笔对象
        self.brush_now = self.brush.subsurface((0, 0), (size * 2, size * 2))

    # 获取画笔大小
    def get_size(self):
        return self.size

    # 设置画笔颜色
    def set_color(self, color):
        self.color = color # 记录选择的颜色
        for i in range(self.brush.get_width()): # 获取画笔的宽度
            for j in range(self.brush.get_height()): #获取画笔的高度
                # 以指定颜色显示画笔
                self.brush.set_at((i, j), color + (self.brush.get_at((i, j)).a,))

    # 获取画笔颜色
    def get_color(self):
        return self.color

    # 绘制动作
    def draw(self, pos):
        if self.drawing: # 判断是否开始绘画
            for p in self._get_points(pos):
                # 在两点之间的每个点上都画上实心点
                pygame.draw.circle(self.screen, self.color, p, int(self.size))
            self.last_pos = pos # 记录画笔最后位置

    # 获取两点之间所有的点位,该函数通过对鼠标坐标前一次记录点与当前记录点之间进行线性插值
    # 从而获得一系列点的坐标,从而使得绘制出来的画笔痕迹更加平滑自然
    def _get_points(self, pos):
        points = [(self.last_pos[0], self.last_pos[1])]
        len_x = pos[0] - self.last_pos[0]
        len_y = pos[1] - self.last_pos[1]
        length = math.sqrt(len_x ** 2 + len_y ** 2)
        step_x = len_x / length
        step_y = len_y / length
        for i in range(int(length)):
            points.append(
                (points[-1][0] + step_x, points[-1][1] + step_y))
        # 对 points 中的点坐标进行四舍五入取整
        points = map(lambda x: (int(0.5 + x[0]), int(0.5 + x[1])), points)
        return list(set(points)) # 去除坐标相同的点

class Menu(object):
    """
    菜单类
    """
    def __init__(self, screen):
        self.screen = screen  # 初始化窗口
        self.brush = None
        self.colors = [  # 颜色表
            (0xff, 0x00, 0xff), (0x80, 0x00, 0x80),
            (0x00, 0x00, 0xff), (0x00, 0x00, 0x80),
            (0x00, 0xff, 0xff), (0x00, 0x80, 0x80),
            (0x00, 0xff, 0x00), (0x00, 0x80, 0x00),
            (0xff, 0xff, 0x00), (0x80, 0x80, 0x00),
            (0xff, 0x00, 0x00), (0x80, 0x00, 0x00),
            (0xc0, 0xc0, 0xc0), (0x00, 0x00, 0x00),
            (0x80, 0x80, 0x80), (0x00, 0xc0, 0x80),
        ]
        self.eraser_color = (0xff, 0xff, 0xff) # 初始颜色
        # 计算每个色块在画板中的坐标值,便于绘制
        self.colors_rect = []
        for (i, rgb) in enumerate(self.colors):  # 方块颜色表
            rect = pygame.Rect(10 + i % 2 * 32, 254 + i / 2 * 32, 32, 32)
            self.colors_rect.append(rect)

        self.pens = [  # 画笔图片
            pygame.image.load("img/pen.png").convert_alpha(),
        ]
        self.erasers = [  # 橡皮图片
            pygame.image.load("img/eraser.png").convert_alpha(),
        ]
        self.erasers_rect = []
        for (i, img) in enumerate(self.erasers):  # 橡皮列表
            rect = pygame.Rect(10, 10 + (i + 1) * 64, 64, 64)
            self.erasers_rect.append(rect)

        self.pens_rect = []
        for (i, img) in enumerate(self.pens):  # 画笔列表
            rect = pygame.Rect(10, 10 + i * 64, 64, 64)
            self.pens_rect.append(rect)

        self.sizes = [  # 加减号图片
            pygame.image.load("img/plus.png").convert_alpha(),
            pygame.image.load("img/minus.png").convert_alpha()
        ]

        # 计算坐标,便于绘制
        self.sizes_rect = []
        for (i, img) in enumerate(self.sizes):
            rect = pygame.Rect(10 + i * 32, 138, 32, 32)
            self.sizes_rect.append(rect)

    def set_brush(self, brush):  # 设置画笔对象
        self.brush = brush

    def draw(self):  # 绘制菜单栏
        for (i, img) in enumerate(self.pens): # 绘制画笔样式按钮
            self.screen.blit(img, self.pens_rect[i].topleft)
        for (i, img) in enumerate(self.erasers): # 绘制橡皮按钮
            self.screen.blit(img, self.erasers_rect[i].topleft)
        for (i, img) in enumerate(self.sizes): # 绘制 + - 按钮
            self.screen.blit(img, self.sizes_rect[i].topleft)
        # 绘制用于实时展示画笔的小窗口
        self.screen.fill((255, 255, 255), (10, 180, 64, 64))
        pygame.draw.rect(self.screen, (0, 0, 0), (10, 180, 64, 64), 1)
        size = self.brush.get_size()
        x = 10 + 32
        y = 180 + 32
        # 在窗口中展示画笔
        pygame.draw.circle(self.screen, self.brush.get_color(), (x, y), int(size))
        for (i, rgb) in enumerate(self.colors): # 绘制色块
            pygame.draw.rect(self.screen, rgb, self.colors_rect[i])

    def click_button(self, pos):
        # 点击加减号事件
        for (i, rect) in enumerate(self.sizes_rect):
            if rect.collidepoint(pos):
                if i:  # i == 1, size down
                    self.brush.set_size(self.brush.get_size() - 0.5)
                else:
                    self.brush.set_size(self.brush.get_size() + 0.5)
                return True
        # 点击颜色按钮事件
        for (i, rect) in enumerate(self.colors_rect):
            if rect.collidepoint(pos):
                self.brush.set_color(self.colors[i])
                return True
        # 点击橡皮按钮事件
        for (i, rect) in enumerate(self.erasers_rect):
            if rect.collidepoint(pos):
                self.brush.set_color(self.eraser_color)
                return True
        return False

class Paint(object):
    """
    窗口绘制类
    """
    def __init__(self):
        self.screen = pygame.display.set_mode((800, 600)) # 显示窗口
        pygame.display.set_caption("超级画板") # 设置窗口标题
        self.clock = pygame.time.Clock() # 控制速率
        self.brush = Brush(self.screen) # 创建画刷对象
        self.menu = Menu(self.screen) # 创建窗口菜单
        self.menu.set_brush(self.brush) # 设置默认画刷

    def clear_screen(self):
        self.screen.fill((255, 255, 255))  # 填充空白

    def run(self):
        self.clear_screen() # 清除屏幕
        while True:
            # 设置fps,表示每秒执行30次(注意:30不是毫秒数)
            self.clock.tick(30)
            for event in pygame.event.get(): # 遍历所有事件
                if event.type == QUIT:  # 退出事件
                    return
                elif event.type == KEYDOWN:  # 按键事件
                    # 按ESC键清空画板
                    if event.key == K_ESCAPE:  # ESC按键事件
                        self.clear_screen()
                elif event.type == MOUSEBUTTONDOWN:  # ;鼠标左键按下事件
                    if ((event.pos)[0] <= 74 and self.menu.click_button(event.pos)):  # 未点击画板按钮
                        pass
                    else:
                        self.brush.start_draw(event.pos)  # 开始绘画
                elif event.type == MOUSEMOTION:  # 鼠标移动事件
                    self.brush.draw(event.pos)  # 绘画动作
                elif event.type == MOUSEBUTTONUP:  # 鼠标左键松开事件
                    self.brush.end_draw()  # 停止绘画
            self.menu.draw()
            pygame.display.update()  # 更新画板

  

# 导入Pygame
try:
    import pygame
except ModuleNotFoundError:
    print('正在安装pygame,请稍等...')
    os.system('pip install pygame') # 安装pygame模块
import tools # 导入tools模块

# 检测Python版本号
__MAJOR, __MINOR, __MICRO = sys.version_info[0], sys.version_info[1], sys.version_info[2]
if __MAJOR < 3:
    print('Python版本号过低,当前版本为 %d.%d.%d, 请重装Python解释器' % (__MAJOR, __MINOR, __MICRO))
    time.sleep(2)
    exit()

if __name__ == '__main__':
    # 创建Paint类的对象
    paint = tools.Paint()
    try:
        paint.run()  # 启动主窗口
    except Exception as e:
        print(e)

  

 

标签:draw,python,self,0x00,pygame,size,rect,brush
From: https://www.cnblogs.com/geovindu/p/17492497.html

相关文章

  • Python学习笔记
    函数调试相关F8stepover单步执行会把函数调用视作一行,直接执行,不会进入函数内部F7stepinto也可以单步执行,如果是函数,会进入函数内部函数注释使用三对引号参数相关形参和实参:定义函数时使用的参数是形参,调用函数时传入的函数是实参局部变量和全局变量:局部变量是在函......
  • BUUCTF:[SUCTF 2019]Pythonginx
    @app.route('/getUrl',methods=['GET','POST'])defgetUrl():url=request.args.get("url")host=parse.urlparse(url).hostnameifhost=='suctf.cc':return"我扌yourproblem?111&q......
  • python读取csv文件进行绘图
    2023-06-19   https://www.cnblogs.com/NJ-Leon/  1.matplotlib库安装升级pip: python3-mpipinstall-Upip 安装matplotlib库: python3-mpipinstall-Umatplotlib 2.python代码importcsvimportmatplotlib.pyplotaspltfile_path......
  • linux中进入python交互解释器Tab补全功能
    进入python交互解释器后,按tab键默认是缩进功能,而不是代码补全。为了实现代码补全,可以采用如下操作:1、创建指令补全文件[root@room8pc16 ~]# vim /usr/local/bin/tab.pyfrom rlcompleter import readlinereadline.parse_and_bind('tab: complete')2、配置环境变量,在~/.bashrc......
  • python基础 | python中为什么没有自增运算符?
    学过Java或者C语言的同学在使用python时发现之前很方便的自增运算在python中无法使用,要想弄清楚这个问题,首先需要明白什么是自增运算符?自增运算符:自增运算符的作用是在运算结束前将变量的值加1。自增运算符一般存在于C/C++/C#/Java等高级语言中。自增运算是在该数字原来的内存地......
  • python进阶手册(2)
    目录语法细节函数参数默认参数传引用可变(数量)参数列表解析正则表达式仅查找第一次匹配的文本串编译后的正则表达式对象多重匹配函数参数位置参数关键字参数可变(数量)关键字参数函数作为函数的参数函数工厂匿名函数正则表达式语法细节编码声明Python脚本第一或第二行的注释匹......
  • python二维列表(矩阵转置)
    1.方法一lst1=[[2,0,0,2],[2,1,2,1],[3,1,1,2],[0,1,0,1],]lst1[:]=[list(reversed(item))foriteminlst1]print(lst1)2.方法二lst2=[[2,0,0,2],[2,1,2,1],[3,1,1,2],[0,1,0,1],]lst2[:]=[list(item)foriteminzip(*l......
  • python3 subprocess.getoutput(cmd) 执行linux命令进入交互模式后一直卡住了
    进入交互模式是我们预期之外的,记录一下。进入交互之后linux一直等待你的输入,所有subprocess.getoutput()就一直卡着呢~,我们加入timeout通过学习subprocess中支持timeout有:getoutput并不支持timeout参数尝试了callcheck_allcheck_output这几个方法之后并不能解决Linux交......
  • 软件测试|Python科学计算神器numpy教程(一)
    前言之前我们使用matplotlib绘制了不一样的图形,其实在我们的绘制图像时,我们输入的数据都是经过处理之后再通过matplotlib以及pillow进行绘制的。我们在绘制图形的脚本里,引入了一个对数组执行数学运算和相关逻辑运算的第三方库——Numpy,当然numpy功能不止于此,它还是python科学计算的......
  • python3 面向对象编程--类的封装和继承
    #python3importrefromurllibimportrequestimportosclassPosterSpider(object):def__init__(self,path='./'):self.path=path#theentryofthisprocessdefgetStart(self,url):page=self.reqPage(url)......