【计算机视觉】二、图像形成——实验:2D变换编辑器2.0(Pygame)

news2024/10/7 18:28:58

文章目录

  • 一、向量和矩阵的基本运算
  • 二、几何基元和变换
    • 1、几何基元(Geometric Primitives)
    • 2、几何变换(Geometric Transformations)
    • 2D变换编辑器
      • 0. 项目结构
      • 1. Package: gui
        • button.py
        • window.py
          • 1. `__init__(self, width, height, title)`
          • 2. `add_buttons(self)`
          • 3. `clear(self)`
          • 4. `draw(self, original_img)`
          • 5. `handle_events(self, event)`
          • 6. `save_image(self)`
          • 7. 代码整合
      • 2. Package: transformations
        • image_generators.py
        • image_transformers.py
      • 3. main.py
      • 4. 效果展示
        • 选择图像
        • 图像操作
        • 保存图像

一、向量和矩阵的基本运算

【计算机视觉】二、图像形成:1、向量和矩阵的基本运算:线性变换与齐次坐标

二、几何基元和变换

1、几何基元(Geometric Primitives)

  几何基元是计算机图形学中最基本的图形对象,它们是构建更复杂图形的基础单元。常见的几何基元包括:

  • 点(Point): 由一对或一组坐标值表示的零维对象。
  • 线段(Line Segment): 由两个端点确定的一维对象。
  • 多边形(Polygon): 由一系列顶点连接而成的闭合平面图形,是二维对象。
  • 曲线(Curve): 由一系列控制点和方程确定的平滑曲线,如贝塞尔曲线、样条曲线等。
  • 圆(Circle): 由一个圆心和半径确定的二维闭合曲线。
  • 球体(Sphere): 由一个球心和半径确定的三维闭合曲面。

  这些基本的几何基元可以通过组合、变换等操作构建出更加复杂的图形对象,如三维模型、场景等。

2、几何变换(Geometric Transformations)

【计算机视觉】二、图像形成:2、几何基元和几何变换:2D变换

在这里插入图片描述

2D变换编辑器

【计算机视觉】二、图像形成——实验:2D变换编辑器(Pygame)

0. 项目结构

image_transformations/
├── main.py
├── gui/
│   ├── __init__.py
│   ├── button.py
│   └── window.py
├── transformations/
│   ├── __init__.py
│   ├── image_generators.py
│   └── image_transformers.py
├── utils/
│   ├── __init__.py
│   └── file_utils.py

1. Package: gui

button.py
import pygame


# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, color):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.darker_color = (max(color[0] - 50, 0), max(color[1] - 50, 0), max(color[2] - 50, 0))  # 计算一个较暗的颜色

    def draw(self, surface):
        pygame.draw.rect(surface, self.color, self.rect)
        font = pygame.font.Font(None, 24)
        text = font.render(self.text, True, (255, 255, 255))
        text_rect = text.get_rect(center=self.rect.center)
        surface.blit(text, text_rect)

    def is_clicked(self, pos):
        return self.rect.collidepoint(pos)
window.py

   Window 类负责管理整个窗口及其界面,只需要创建一个 Window 对象,并在主循环中调用 clear()draw()handle_events() 方法即可。这样可以使代码更加模块化和易于维护。

1. __init__(self, width, height, title)
  • 初始化窗口对象。
  • 设置窗口的宽度、高度和标题。
  • 创建一个空列表 self.buttons 来存储所有按钮对象。
  • 初始化当前层级 self.current_layer 为 1。
  • 初始化其他变量,如选择的变换操作 self.selected_transform、变换后的图像 self.transformed_img、原始图像 self.original_img、鼠标拖拽相关变量等。
  • 调用 self.add_buttons() 方法添加按钮。
    def __init__(self, width, height, title):
        self.width = width
        self.height = height
        self.window = pygame.display.set_mode((width, height))
        pygame.display.set_caption(title)

        self.buttons = []
        self.current_layer = 1
        self.selected_transform = None
        self.transformed_img = None
        self.original_img = None
        self.mouse_dragging = False
        self.drag_start_pos = (0, 0)
        self.drag_offset = (0, 0)
        self.translation_offset = (0, 0)

        self.add_buttons()
        # pygame.display.set_icon(pygame.image.load("icon.png"))  # 加载图标文件
        self.pygame_to_numpy_map = {}
2. add_buttons(self)
  • 创建第一层界面的三个按钮对象。
  • 创建第二层界面的八个按钮对象。
  • 将所有按钮对象添加到 self.buttons 列表中。
   def add_buttons(self):
        # 添加第一层界面按钮
        self.buttons.append(Button(50, 50, 200, 50, "Select Image", (255, 0, 0)))
        self.buttons.append(Button(350, 50, 200, 50, "Generate Square", (0, 255, 0)))
        self.buttons.append(Button(650, 50, 200, 50, "Generate Circle", (0, 0, 255)))

        # 添加第二层界面按钮
        # - "Translate"按钮颜色为红色
        # - "Rotate"按钮颜色为橙色 `(2
        # - "Isotropic Scale"按钮
        # - "Scale"按钮颜色为青色 `(0,
        # - "Mirror"按钮颜色为蓝色 `(0
        # - "Shear"按钮颜色为紫色 `(12
        # 问:为什么没有黄色
        # 答:黄色太耀眼了………
        self.buttons.append(Button(50, 50, 150, 50, "Translate", (255, 0, 0)))
        self.buttons.append(Button(250, 50, 150, 50, "Rotate", (255, 165, 0)))
        self.buttons.append(Button(450, 50, 150, 50, "Isotropic Scale", (0, 255, 0)))
        self.buttons.append(Button(650, 50, 150, 50, "Scale", (0, 255, 255)))
        self.buttons.append(Button(50, 150, 150, 50, "Mirror", (0, 0, 255)))
        self.buttons.append(Button(250, 150, 150, 50, "Shear", (128, 0, 128)))
        self.buttons.append(Button(450, 150, 150, 50, "Back to Selection", (128, 128, 128)))
        # 新增"保存图片"功能
        self.buttons.append(Button(650, 150, 150, 50, "Save Image", (0, 128, 0)))

3. clear(self)
  • 使用灰色色 (220, 220, 220) 填充窗口~ui界面背景。
	 def clear(self):
	        self.window.fill((220, 220, 220)) 
        
4. draw(self, original_img)
  • 根据当前层级绘制相应的界面。
  • 在第一层界面中,绘制前三个按钮。
  • 在第二层界面中,绘制原始图像和后七个按钮。
  • 在第三层界面中,绘制原始图像、变换后的图像、后七个按钮和选择的变换操作文本。
    def draw(self, original_img):
        # # 绘制标题栏
        # pygame.draw.rect(self.window, (100, 100, 100), (0, 0, self.width, 50))  # 绘制矩形背景
        # font = pygame.font.Font(None, 36)
        # text = font.render("Image Transformations", True, (255, 255, 255))  # 绘制白色文本
        # self.window.blit(text, (10, 10))
        if self.current_layer == 1:
            # 绘制第一层界面
            for button in self.buttons[:3]:
                button.draw(self.window)

        elif self.current_layer == 2:
            # 绘制第二层界面
            if original_img is not None:
                self.window.blit(original_img, (50, 250))
            for button in self.buttons[3:]:
                button.draw(self.window)

        elif self.current_layer == 3:
            # 绘制第三层界面
            if self.original_img is not None:
                self.window.blit(self.original_img, (50, 250))
            if self.transformed_img is not None:
                self.window.blit(self.transformed_img, (350, 250))
            for button in self.buttons[3:]:  # 在第三层界面上方显示操作按钮
                button.draw(self.window)
            if self.selected_transform is not None:
                font = pygame.font.Font(None, 36)
                text = font.render(f"Selected Transform: {self.selected_transform}", True, (255, 255, 255))
                text_rect = text.get_rect(center=(self.width // 2, 222))
                self.window.blit(text, text_rect)

5. handle_events(self, event)
  • 处理各种事件。
  • 如果事件类型是 pygame.MOUSEBUTTONDOWN,则处理鼠标按下事件:
    • 在第一层界面中,点击相应按钮加载图像或生成图形。
    • 在第二层和第三层界面中,点击相应按钮选择变换操作。
    • 如果点击左键,开始鼠标拖拽操作。
  • 如果事件类型是 pygame.MOUSEBUTTONUP,则处理鼠标释放事件,结束鼠标拖拽操作。
  • 如果事件类型是 pygame.MOUSEMOTION,则处理鼠标移动事件:
    • 如果处于第三层界面并正在拖拽,则根据选择的变换操作和鼠标移动量执行相应的变换,并更新变换后的图像。
6. save_image(self)
    def save_image(self):
        if self.transformed_img is not None:
            root = Tk()
            root.withdraw()
            file_path = filedialog.asksaveasfilename(defaultextension=".png")
            if file_path:
                pygame.image.save(self.transformed_img, file_path)

7. 代码整合
import numpy as np
import pygame
from gui.button import Button
from transformations.image_generators import *
from transformations.image_transformers import *
from tkinter import filedialog
from tkinter import Tk


class Window:
    def __init__(self, width, height, title):
        self.width = width
        self.height = height
        self.window = pygame.display.set_mode((width, height))
        pygame.display.set_caption(title)

        self.buttons = []
        self.current_layer = 1
        self.selected_transform = None
        self.transformed_img = None
        self.original_img = None
        self.mouse_dragging = False
        self.drag_start_pos = (0, 0)
        self.drag_offset = (0, 0)
        self.translation_offset = (0, 0)

        self.add_buttons()
        # pygame.display.set_icon(pygame.image.load("icon.png"))  # 加载图标文件
        self.pygame_to_numpy_map = {}

	    # def pygame_to_numpy(self, surface):
	    #     if surface in self.pygame_to_numpy_map:
	    #         return self.pygame_to_numpy_map[surface]
	    #     else:
	    #         numpy_array = np.transpose(np.array(pygame.surfarray.pixels3d(surface)), (1, 0, 2))
	    #         self.pygame_to_numpy_map[surface] = numpy_array
	    #         return numpy_array
	    # 
	    # def numpy_to_pygame(self, numpy_array):
	    #     surface = pygame.Surface(numpy_array.shape[:2][::-1], pygame.SRCALPHA)
	    #     pygame.surfarray.blit_array(surface, np.transpose(numpy_array, (1, 0, 2)))
	    #     return surface

    def add_buttons(self):
        # 添加第一层界面按钮
        self.buttons.append(Button(50, 50, 200, 50, "Select Image", (255, 0, 0)))
        self.buttons.append(Button(350, 50, 200, 50, "Generate Square", (0, 255, 0)))
        self.buttons.append(Button(650, 50, 200, 50, "Generate Circle", (0, 0, 255)))

        # 添加第二层界面按钮
        # - "Translate"按钮颜色为红色
        # - "Rotate"按钮颜色为橙色 `(2
        # - "Isotropic Scale"按钮
        # - "Scale"按钮颜色为青色 `(0,
        # - "Mirror"按钮颜色为蓝色 `(0
        # - "Shear"按钮颜色为紫色 `(12
        # 问:为什么没有黄色
        # 答:黄色太耀眼了………
        self.buttons.append(Button(50, 50, 150, 50, "Translate", (255, 0, 0)))
        self.buttons.append(Button(250, 50, 150, 50, "Rotate", (255, 165, 0)))
        self.buttons.append(Button(450, 50, 150, 50, "Isotropic Scale", (0, 255, 0)))
        self.buttons.append(Button(650, 50, 150, 50, "Scale", (0, 255, 255)))
        self.buttons.append(Button(50, 150, 150, 50, "Mirror", (0, 0, 255)))
        self.buttons.append(Button(250, 150, 150, 50, "Shear", (128, 0, 128)))
        self.buttons.append(Button(450, 150, 150, 50, "Back to Selection", (128, 128, 128)))
        # 新增"保存图片"功能
        self.buttons.append(Button(650, 150, 150, 50, "Save Image", (0, 128, 0)))

    def clear(self):
        self.window.fill((220, 220, 220))  # ui界面灰色背景

    def draw(self, original_img):
        # # 绘制标题栏
        # pygame.draw.rect(self.window, (100, 100, 100), (0, 0, self.width, 50))  # 绘制矩形背景
        # font = pygame.font.Font(None, 36)
        # text = font.render("Image Transformations", True, (255, 255, 255))  # 绘制白色文本
        # self.window.blit(text, (10, 10))
        if self.current_layer == 1:
            # 绘制第一层界面
            for button in self.buttons[:3]:
                button.draw(self.window)

        elif self.current_layer == 2:
            # 绘制第二层界面
            if original_img is not None:
                self.window.blit(original_img, (50, 250))
            for button in self.buttons[3:]:
                button.draw(self.window)

        elif self.current_layer == 3:
            # 绘制第三层界面
            if self.original_img is not None:
                self.window.blit(self.original_img, (50, 250))
            if self.transformed_img is not None:
                self.window.blit(self.transformed_img, (350, 250))
            for button in self.buttons[3:]:  # 在第三层界面上方显示操作按钮
                button.draw(self.window)
            if self.selected_transform is not None:
                font = pygame.font.Font(None, 36)
                text = font.render(f"Selected Transform: {self.selected_transform}", True, (255, 255, 255))
                text_rect = text.get_rect(center=(self.width // 2, 222))
                self.window.blit(text, text_rect)

    def handle_events(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            if self.current_layer == 1:  # 第一层界面
                for button in self.buttons[:3]:
                    if button.is_clicked(mouse_pos):
                        if button.text == "Select Image":
                            root = Tk()
                            root.withdraw()
                            self.file_path = filedialog.askopenfilename(title="Select Image")
                            if self.file_path:
                                self.original_img = pygame.image.load(self.file_path)
                                self.original_img = pygame.transform.scale(self.original_img, (256, 256))
                                self.current_layer = 2
                        elif button.text == "Generate Square":
                            self.original_img = generate_square(256, (255, 255, 255))
                            self.current_layer = 2
                        elif button.text == "Generate Circle":
                            self.original_img = generate_circle(128, (255, 255, 255))
                            self.current_layer = 2
            elif self.current_layer == 2 or self.current_layer == 3:  # 第二层和第三层界面
                for button in self.buttons[3:]:
                    if button.is_clicked(mouse_pos):
                        if button.text == "Save Image":
                            self.save_image()
                        elif button.text == "Back to Selection":  # 返回选择界面
                            self.original_img = None
                            self.selected_transform = None
                            self.transformed_img = None
                            self.current_layer = 1
                        else:
                            self.selected_transform = button.text
                            self.transformed_img = self.original_img.copy()
                            if self.current_layer == 2:
                                self.current_layer = 3

            if event.button == 1:  # 鼠标左键
                self.mouse_dragging = True
                self.drag_start_pos = mouse_pos

        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:  # 鼠标左键
                self.mouse_dragging = False

        elif event.type == pygame.MOUSEMOTION:
            if self.mouse_dragging and self.current_layer == 3:
                pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_HAND)
                mouse_pos = pygame.mouse.get_pos()
                self.drag_offset = (mouse_pos[0] - self.drag_start_pos[0], mouse_pos[1] - self.drag_start_pos[1])
                if self.selected_transform == "Translate":
                    self.translation_offset = self.drag_offset  # 更新平移偏移量
                    self.transformed_img = translate(self.original_img, self.translation_offset[0],
                                                     self.translation_offset[1])
                elif self.selected_transform == "Rotate":
                    angle = self.drag_offset[0]
                    self.transformed_img = rotate(self.original_img, angle)
                elif self.selected_transform == "Isotropic Scale":
                    scale_factor = max(0.1, 1 + self.drag_offset[0] / 100)  # 限制缩放比例在0.1到无穷大之间
                    self.transformed_img = isotropic_scale(self.original_img, scale_factor)
                elif self.selected_transform == "Scale":
                    scale_x = max(0.1, 1 + self.drag_offset[0] / 100)  # 限制x方向缩放比例在0.1到无穷大之间
                    scale_y = max(0.1, 1 + self.drag_offset[1] / 100)  # 限制y方向缩放比例在0.1到无穷大之间
                    self.transformed_img = scale(self.original_img, scale_x, scale_y)
                elif self.selected_transform == "Mirror":
                    if self.drag_offset[0] > 0:
                        mirror_type = 'horizontal'
                    else:
                        mirror_type = 'vertical'
                    self.transformed_img = mirror(self.original_img, mirror_type)
                elif self.selected_transform == "Shear":
                    shear_x = self.drag_offset[0] / 100
                    shear_y = self.drag_offset[1] / 100
                    self.transformed_img = shear(self.original_img, shear_x, shear_y)
            else:
                pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_ARROW)
                # 在鼠标拖拽时将鼠标指针设置为手型, 否则设置为默认箭头形状。

    def save_image(self):
        if self.transformed_img is not None:
            root = Tk()
            root.withdraw()
            file_path = filedialog.asksaveasfilename(defaultextension=".png")
            if file_path:
                pygame.image.save(self.transformed_img, file_path)

2. Package: transformations

image_generators.py
import pygame


# 生成正方形图像
def generate_square(size, color):
    img = pygame.Surface((size, size))
    img.fill(color)
    return img


# 生成圆形图像
def generate_circle(radius, color):
    img = pygame.Surface((radius * 2, radius * 2))
    img.fill((0, 0, 0))
    img.set_colorkey((0, 0, 0))
    pygame.draw.circle(img, color, (radius, radius), radius)
    return img

image_transformers.py
import pygame

window_width, window_height = 888, 888


# 平移变换
def translate(img, x, y):
    width, height = img.get_size()
    translated_img = pygame.Surface((window_width, window_height), pygame.SRCALPHA)
    translated_img.blit(img, (x, y))
    return translated_img


# 旋转变换
def rotate(img, angle):
    rotated_img = pygame.transform.rotate(img, angle)
    return rotated_img


# 等比缩放变换
def isotropic_scale(img, scale_factor):
    width, height = img.get_size()
    new_size = (int(width * scale_factor), int(height * scale_factor))
    scaled_img = pygame.transform.scale(img, new_size)
    return scaled_img


# 缩放变换
def scale(img, scale_x, scale_y):
    width, height = img.get_size()
    new_width = int(width * scale_x)
    new_height = int(height * scale_y)
    scaled_img = pygame.transform.scale(img, (new_width, new_height))
    return scaled_img


# 镜像变换
def mirror(img, mirror_type):
    if mirror_type == 'horizontal':
        mirrored_img = pygame.transform.flip(img, True, False)
    elif mirror_type == 'vertical':
        mirrored_img = pygame.transform.flip(img, False, True)
    else:
        return img
    return mirrored_img


# 剪切变换
def shear(img, shear_x, shear_y):
    width, height = img.get_size()
    sheared_img = pygame.Surface((width + abs(shear_x * height), height + abs(shear_y * width)))
    sheared_img.set_colorkey((0, 0, 0))
    for x in range(width):
        for y in range(height):
            sheared_img.blit(img, (x + shear_x * y, y + shear_y * x), (x, y, 1, 1))
    return sheared_img
    

3. main.py

import pygame
from gui.window import Window

pygame.init()

window_width, window_height = 888, 888
window = Window(window_width, window_height, "2D Transformations")

running = True
while running:
    # 设置窗口大小
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        window.handle_events(event)

    window.clear()
    window.draw(window.original_img)
    pygame.display.flip()

pygame.quit()

4. 效果展示

在这里插入图片描述

选择图像

在这里插入图片描述

图像操作

在这里插入图片描述

保存图像

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WEB前端 HTML 列表表格

列表 有序列表 使用“ol”创建“有序列表”&#xff0c;使用“li”表示“列表项” <body><ol type"1"><li>列表1</li><li>列表2</li><li>列表3</li></ol><ol type"A"><li>列表A<…

Redis进阶——redis消息队列

目录 redis消息队列认识消息队列基于List实现消息队列如何基于List结构模拟消息队列基于List的消息队列有哪些优缺点&#xff1f; 基于PubSub的消息队列基于Stream的消息队列读取消息的方式之一&#xff1a;XREAD基于Stream的消息队列–消费者组redis三种消息队列的对比 Stream…

Spring炼气之路(炼气二层)

一、bean的配置 1.1 bean的基础配置 id&#xff1a; bean的id&#xff0c;使用容器可以通过id值获取对应的bean&#xff0c;在一个容器中id值唯一 class&#xff1a; bean的类型&#xff0c;即配置的bean的全路径类名 <bean id"bookDao" class "com.zhang…

Java八股文(MyBatis Plus)

Java八股文のMyBatis Plus MyBatis Plus MyBatis Plus MyBatis Plus 是什么&#xff1f;它与 MyBatis 有什么区别&#xff1f; MyBatis Plus 是基于 MyBatis 进行扩展的一款持久层框架&#xff0c;它提供了一系列增强功能&#xff0c;简化了 MyBatis 的使用。 与 MyBatis 相比…

(十八)【Jmeter】取样器(Sampler)之BeanShell 取样器

简述 操作路径如下: 作用:通过Beanshell脚本来编写自定义请求。配置:编写Beanshell脚本代码,实现请求逻辑。使用场景:在JMeter中利用Beanshell脚本语言的特性进行自定义请求。优点:可以利用Beanshell脚本语言的丰富功能。缺点:脚本语言的性能可能不如其他编译语言,且…

论文阅读——SpectralGPT

SpectralGPT: Spectral Foundation Model SpectralGPT的通用RS基础模型&#xff0c;该模型专门用于使用新型3D生成预训练Transformer&#xff08;GPT&#xff09;处理光谱RS图像。 重建损失由两个部分组成&#xff1a;令牌到令牌和频谱到频谱 下游任务&#xff1a;

Linux进程管理:(六)SMP负载均衡

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 前置知识 1.1 CPU管理位图 内核…

使用Java Runtime执行docker下的mysqldump

Runtime直接使用 docker exec mysql mysqldump -u%s -p%s cblog > %s&#xff08;%s是需要填充的数据&#xff09;&#xff0c;命令无法执行并且不会报错&#xff0c;需要使用字符串数组加入"sh", “-c”&#xff0c;具体代码示例&#xff1a; /*** MySQL数据备份…

无线局域网——wlan

目录 一.wlan的含义和发展 二.wlan技术带来的挑战 1.企业办公场景多样 2.位置速度的要求 3.安全的要求 4.规范的挑战 三.家庭和企业不同的部署需求 1.胖AP模式组网 2.AC瘦AP模式组网 3.组网模式的不同 四.三层隧道转发实验 1.拓扑 2.AP上线 核心交换机vlan ​编辑…

Magical Combat VFX

这个包包含30个可供游戏使用的VFX,有各种口味,为您的游戏增添趣味! 所有VFX都经过了很好的优化,可以在所有平台上使用。 这个包特别有一堆闪电魔法,有两种主要的变体,一种是深色的,另一种是浅色的。但它也提供了一系列其他视觉效果,如神圣咒语、音乐主题等等! 我们提供…

解决谷歌浏览器最新chrome94版本CORS跨域问题

项目场景&#xff1a; 谷歌浏览器升级到chrome94版本出现CORS跨域问题 问题描述 解决谷歌浏览器最新chrome94版本CORS跨域问题。 CORS跨域问题&#xff1a; 升级谷歌浏览器最新chrome94版本后&#xff0c;提示Access to XMLHttpRequest at ‘http://localhost:xxxx/api’ fro…

uni-app发布 h5 与ASP .NET MVC 后台 发布 到 IIS的同一端口 并配置跨域

iis 安装URL重写 选择对应的后台项目&#xff0c;进行url重写 编辑【模式】部分的内容的重写规则&#xff0c;我这里是h5中请求的前缀是api&#xff0c;大家可以根据自己的前缀进行修改。 编写【操作类型】为重写&#xff0c;并写重写url&#xff0c;按照图中设置即可。 uni…

使用Python构建RESTful API的最佳实践【第137篇—RESTful API】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python构建RESTful API的最佳实践 在当今的软件开发中&#xff0c;构建RESTful API已经…

【系统性】 循序渐进学C++

循序渐进学C 第一阶段&#xff1a;基础 一、环境配置 1.1.第一个程序&#xff08;基本格式&#xff09; ​ #include <iosteam> using namespace std;int main(){cout<<"hello world"<<endl;system("pause"); }​ 模板 #include &…

【开源鸿蒙】编译OpenHarmony轻量系统QEMU RISC-V版

文章目录 一、背景介绍二、准备OpenHarmony源代码三、准备hb命令3.1 安装hb命令3.2 检查hb命令 四、编译RISC-V架构的OpenHarmony轻量系统4.1 设置hb构建目标4.2 启动hb构建过程 五、问题解决5.1 hb set 报错问题解决 六、参考链接 开源鸿蒙坚果派&#xff0c;学习鸿蒙一起来&a…

【开源】SpringBoot框架开发二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

HarmonyOS NEXT应用开发—发布图片评论

介绍 本示例将通过发布图片评论场景&#xff0c;介绍如何使用startAbilityForResult接口拉起相机拍照&#xff0c;并获取相机返回的数据。 效果图预览 使用说明 通过startAbilityForResult接口拉起相机&#xff0c;拍照后获取图片地址。 实现思路 创建CommentData类&#…

vue ui 无反应解决方法

cmd 输入vue ui 无反应解决方法 在学习vuex的过程中&#xff0c;需要用到vue ui 建立项目&#xff0c;遇到的问题记录一下&#xff0c;希望能够以帮助有问题的其他人 查看vue版本 vue --version 或者 vue -V 发现vue版本才2.9.6 由于vue ui 命令需要vue3.0以上&#xff0c;…

如何实现图片上传至服务器

在绝大多数的项目中都会涉及到文件上传等&#xff0c;下面我们来说一下技术派中是如何实现原生图片上传的&#xff0c;这个功能说起来简单&#xff0c;但其实对于技术还是有考验的。图片的上传涉及到IO读写&#xff0c;一个文件上传的功能&#xff0c;就可以把IO流涉及到的知识…

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…