Python |GIF 解析与构建(3):简单哈希压缩256色算法

news2025/6/1 23:33:02

Python |GIF 解析与构建(3):简单哈希压缩256色算法

目录

Python |GIF 解析与构建(3):简单哈希压缩256色算法

一、算法性能表现

二、算法核心原理与实现

(一)简单哈希算法逻辑

1. 颜色分量压缩

2. 加权灰度值计算

3. 旋转哈希生成

(二)图像压缩流程

三、图像质量评估实现

(一)PSNR 计算

(二)SSIM 计算

四、算法优缺点与应用场景

(一)优势

(二)局限性

(三)适用场景

五、总结与改进方向


在图像处理领域,压缩算法的效率与效果始终是研究的核心方向之一。本文将聚焦于一种适用于 256 色 GIF 的简单哈希压缩算法,通过实际案例分析其压缩性能、技术实现及应用场景。

一、算法性能表现

该算法在不同尺寸、类型的图像上在同类的算法之中展现出了中游水平的压缩能力和处理图像质量能力,在GIF256色压缩可以很容易的构建出来,以下是具体测试数据:

图像类型原始尺寸原始大小压缩后大小压缩率PSNR(dB)SSIM
900P 全屏截图1600×900740KB224KB69.73%24.480.8358
900P 全屏截图1600×900477KB238KB50.1%24.830.8997
小型图片300×16039KB7KB82.05%27.980.8877
任务栏截图1260×4027KB13KB51.8%25.100.9448

关键指标说明

  • 压缩率:文件体积缩减比例,数值越高表示压缩效果越显著(如小型图片压缩率达 82.05%)。
  • PSNR(峰值信噪比):衡量图像失真程度,数值越高表示画质保留越好(任务栏截图 PSNR 为 25.10dB,接近人眼可接受范围)。
  • SSIM(结构相似性):评估图像结构相似度,取值越接近 1 表示画质越接近原图(任务栏截图 SSIM 达 0.9448,视觉效果接近无损)。

二、算法核心原理与实现

(一)简单哈希算法逻辑

1. 颜色分量压缩

通过右移操作降低颜色精度:

def shift_bytes_data(data):
    return bytes(c >> 5 for c in data)  # 将RGB各分量从8位压缩为3位(0-7)

原理:利用人眼对颜色细节敏感度较低的特性,通过舍弃低位数据减少颜色数量。

2. 加权灰度值计算

结合人眼对 RGB 三通道的敏感度差异(绿光 > 红光 > 蓝光):

r, g, b = data[0], data[1], data[2]
weighted_sum = (r * 299 + g * 587 + b * 114) // 1000  # 近似计算亮度值

作用:将彩色信息转化为亮度特征,为哈希值提供感知层面的鲁棒性。

3. 旋转哈希生成

通过位移与异或运算增强哈希值的扩散性:

rotated_hash = ((r << 5) ^ g ^ (b >> 3)) & 0xFF  # 混合RGB分量并限制值域
hash_value = (weighted_sum + rotated_hash) & 0xFF  # 合并亮度与色彩特征

优势:减少哈希冲突概率,确保相似颜色生成不同哈希值。

(二)图像压缩流程

  1. 像素数据处理
    将图像转换为 RGB 模式,提取像素列表:

    with Image.open("1.png").convert('RGB') as img:
        pixels = list(img.getdata())  # 获取所有像素的(R, G, B)元组
    
  2. 哈希映射构建
    对每个像素生成哈希值,统计唯一哈希数量(即压缩后颜色数):

    image_set = set([simple_hash_unrolled(bytes(i)) for i in pixels])
    print("压缩数量:", len(image_set))  # 输出唯一哈希值总数
    
  3. 颜色映射与重建
    创建哈希值到原始颜色的映射表,用映射颜色重建图像:

    hash_map = {key: pixels[image_hash.index(s)] for key in image_set}  # 记录每个哈希对应的原始颜色
    new_image = [hash_map.get(x, x) for x in image_hash]  # 用映射颜色替换像素值
    

三、图像质量评估实现

(一)PSNR 计算

基于均方误差(MSE)评估像素级差异:

def calculate_psnr(original_img, compressed_img):
    original = np.array(original_img).astype(np.float64)
    compressed = np.array(compressed_img).astype(np.float64)
    mse = np.mean((original - compressed) ** 2)
    return 20 * np.log10(255.0 / np.sqrt(mse))  # 假设像素值范围0-255

(二)SSIM 计算

从亮度、对比度、结构三方面评估图像相似性:

def calculate_ssim(original_img, compressed_img):
    original = np.array(original_img)
    compressed = np.array(compressed_img)
    if len(original.shape) == 3:  # 彩色图像分通道计算
        return np.mean([ssim(original[:, :, i], compressed[:, :, i], data_range=255) for i in range(3)])
    else:  # 灰度图像直接计算
        return ssim(original, compressed, data_range=255)

四、算法优缺点与应用场景

(一)优势

  • 速度快:压缩耗时约 5 秒(针对 1600×900 图像),适合实时或批量处理。
  • 实现简单:无需复杂数学变换,仅通过位运算和哈希映射完成压缩。
  • 适应性强:在文字图标(如任务栏)、大面积单色区域图像中表现优异(SSIM>0.9)。

(二)局限性

  • 颜色损失明显:在高色彩丰富度图像中(如自然风景),压缩后可能出现色块化。
  • 压缩率波动大:依赖图像内容,复杂图像压缩率较低(约 50%)。

(三)适用场景

  • UI 界面截图:任务栏、菜单等含大量纯色或重复图案的场景。
  • 简单图标 / 图形:LOGO、线条图等对色彩精度要求不高的图像。
  • 低带宽传输:需要快速压缩传输的简单图像场景(如嵌入式设备)。

五、总结与改进方向

该简单哈希算法为 256 色 GIF 压缩提供了一种轻量级解决方案,平衡了压缩效率与实现复杂度。未来可通过以下方式优化:

  1. 动态颜色量化:结合 K-means 等聚类算法,自适应选择最优颜色子集。
  2. 哈希函数优化:引入更复杂的哈希算法(如感知哈希),提升相似颜色区分度。
  3. 分块处理:对图像分区域应用不同压缩策略,保留高细节区域的色彩精度。

代码如下:

import os
from PIL import Image

"""
此算法压缩256色在gif使用的算法中属于中游
尺寸: 1600x900
PSNR: 24.45 dB
SSIM: 0.8676
原始: 666.91KB | 压缩后: 284.01KB | 压缩率: 57.41%

尺寸: 1600x900
PSNR: 26.44 dB
SSIM: 0.9225
原始: 434.13KB | 压缩后: 219.29KB | 压缩率: 49.49%

尺寸: 300x160
PSNR: 34.48 dB
SSIM: 0.8587
原始: 32.36KB | 压缩后: 9.47KB | 压缩率: 70.75%

尺寸: 690x300
PSNR: 23.46 dB
SSIM: 0.9106
原始: 106.14KB | 压缩后: 71.28KB | 压缩率: 32.84%

尺寸: 480x480
PSNR: 29.43 dB
SSIM: 0.6616
原始: 107.20KB | 压缩后: 17.50KB | 压缩率: 83.67%
"""


# 简单哈希
def simple_hash_unrolled(data):
    # 通过右移来实现对细节的颜色进行进一步压缩
    def shift_bytes_data(data):
        return bytes(c >> 5 for c in data)

    data = shift_bytes_data(data)
    # 提取RGB分量
    r, g, b = data[0], data[1], data[2]
    # 人眼敏感度计算
    weighted_sum = (r * 299 + g * 587 + b * 114) // 1000
    # 旋转哈希:结合位移和异或运算,扩散哈希值分布
    rotated_hash = ((r << 5) ^ g ^ (b >> 3)) & 0xFF
    # 亮度
    brightness_component = max(r, g, b) & 0xFF
    # 计算哈希
    hash_value = (weighted_sum + rotated_hash + brightness_component) & 0xFF
    return hash_value


# 简单压缩
def rgb332_hash(data):
    r = data[0] >> 5  # 3 bits (0-7)
    g = data[1] >> 5  # 3 bits (0-7)
    b = data[2] >> 6  # 2 bits (0-3)
    return (r << 5) | (g << 2) | b


#  亮度
def perceptual_hash(data):
    # 转换到YUV空间,提取亮度(更符合人眼敏感度)
    y = (data[0] * 299 + data[1] * 587 + data[2] * 114) // 1000
    # 结合色度简化
    u = data[1] >> 5  # 3-bit
    v = data[2] >> 5  # 3-bit
    return (y & 0xF8) | (u >> 2) | (v << 3)


# 换位
def enhanced_rotated_hash(data):
    r, g, b = data[0] >> 4, data[1] >> 4, data[2] >> 4  # 4-bit压缩
    # 多重异或+位移扩散
    hash_r = (r << 4) ^ (g << 2) ^ b
    hash_g = (g << 4) ^ (b << 2) ^ r
    hash_b = (b << 4) ^ (r << 2) ^ g
    return (hash_r + hash_g * 3 + hash_b * 5) & 0xFF


# 简单哈希法
with Image.open("1.png").convert('RGB') as img:
    width, height = img.size
    pixels = list(img.getdata())
    print(f"尺寸: {width}x{height}")
    print(f"像素数据: {pixels[:10]} ...")

image_set = set([simple_hash_unrolled(bytes(i)) for i in pixels])
print("压缩数量:", len(image_set))
print("压缩哈希:", image_set)
image_hash = [simple_hash_unrolled(bytes(i)) for i in pixels]

hash_map = {key: (0, 0, 0) for key in image_set}
# 全部哈希遍历映射字典
for s in image_set:
    hash_map[s] = pixels[image_hash.index(s)]  # 字典赋值

new_image = [hash_map.get(x, x) for x in image_hash]
# RGB模式
new_img = Image.new('RGB', (width, height))
# 按行填充
new_img.putdata(new_image)
# 保存为PNG文件
new_img.save('2.png', 'PNG')

import numpy as np
from skimage.metrics import structural_similarity as ssim


def calculate_psnr(original_img: Image.Image, compressed_img: Image.Image) -> float:
    """计算两张图像之间的PSNR值"""
    # 将图像转换为NumPy数组
    original = np.array(original_img).astype(np.float64)
    compressed = np.array(compressed_img).astype(np.float64)

    # 确保图像尺寸相同
    if original.shape != compressed.shape:
        raise ValueError("两张图像的尺寸必须相同")

    # 计算MSE(均方误差)
    mse = np.mean((original - compressed) ** 2)

    # 避免除零错误
    if mse == 0:
        return float('inf')

    # 计算PSNR(假设像素值范围为0-255)
    max_pixel = 255.0
    psnr = 20 * np.log10(max_pixel / np.sqrt(mse))

    return psnr


def calculate_ssim(original_img: Image.Image, compressed_img: Image.Image) -> float:
    """计算两张图像之间的SSIM值"""
    # 将图像转换为NumPy数组
    original = np.array(original_img).astype(np.float64)
    compressed = np.array(compressed_img).astype(np.float64)

    # 确保图像尺寸相同
    if original.shape != compressed.shape:
        raise ValueError("两张图像的尺寸必须相同")

    # 如果是彩色图像,分别计算每个通道的SSIM并取平均
    if len(original.shape) == 3 and original.shape[2] == 3:  # RGB图像
        ssim_values = []
        for i in range(3):  # 分别计算R、G、B通道
            ssim_val = ssim(original[:, :, i], compressed[:, :, i],
                            data_range=compressed[:, :, i].max() - compressed[:, :, i].min())
            ssim_values.append(ssim_val)
        return np.mean(ssim_values)
    else:  # 灰度图像
        return ssim(original, compressed,
                    data_range=compressed.max() - compressed.min())


# 加载图像
original = Image.open("1.png").convert("RGB")
compressed = Image.open("2.png").convert("RGB")

# 计算PSNR和SSIM
psnr_value = calculate_psnr(original, compressed)
ssim_value = calculate_ssim(original, compressed)

print(f"PSNR: {psnr_value:.2f} dB")
print(f"SSIM: {ssim_value:.4f}")

# 替换为你的图片路径
original = "1.png"
compressed = "2.png"
# 获取文件大小(KB)
o_size = os.path.getsize(original) / 1024
c_size = os.path.getsize(compressed) / 1024
# 计算并打印压缩率
ratio = (1 - c_size / o_size) * 100
print(f"原始: {o_size:.2f}KB | 压缩后: {c_size:.2f}KB | 压缩率: {ratio:.2f}%")

import os
from PIL import Image

"""
此算法压缩256色在gif使用的算法中属于中游
尺寸: 1600x900
PSNR: 24.45 dB
SSIM: 0.8676
原始: 666.91KB | 压缩后: 284.01KB | 压缩率: 57.41%

尺寸: 1600x900
PSNR: 26.44 dB
SSIM: 0.9225
原始: 434.13KB | 压缩后: 219.29KB | 压缩率: 49.49%

尺寸: 300x160
PSNR: 34.48 dB
SSIM: 0.8587
原始: 32.36KB | 压缩后: 9.47KB | 压缩率: 70.75%

尺寸: 690x300
PSNR: 23.46 dB
SSIM: 0.9106
原始: 106.14KB | 压缩后: 71.28KB | 压缩率: 32.84%

尺寸: 480x480
PSNR: 29.43 dB
SSIM: 0.6616
原始: 107.20KB | 压缩后: 17.50KB | 压缩率: 83.67%
"""


# 简单哈希
def simple_hash_unrolled(data):
    # 通过右移来实现对细节的颜色进行进一步压缩
    def shift_bytes_data(data):
        return bytes(c >> 5 for c in data)

    data = shift_bytes_data(data)
    # 提取RGB分量
    r, g, b = data[0], data[1], data[2]
    # 人眼敏感度计算
    weighted_sum = (r * 299 + g * 587 + b * 114) // 1000
    # 旋转哈希:结合位移和异或运算,扩散哈希值分布
    rotated_hash = ((r << 5) ^ g ^ (b >> 3)) & 0xFF
    # 亮度
    brightness_component = max(r, g, b) & 0xFF
    # 计算哈希
    hash_value = (weighted_sum + rotated_hash + brightness_component) & 0xFF
    return hash_value


# 简单压缩
def rgb332_hash(data):
    r = data[0] >> 5  # 3 bits (0-7)
    g = data[1] >> 5  # 3 bits (0-7)
    b = data[2] >> 6  # 2 bits (0-3)
    return (r << 5) | (g << 2) | b


#  亮度
def perceptual_hash(data):
    # 转换到YUV空间,提取亮度(更符合人眼敏感度)
    y = (data[0] * 299 + data[1] * 587 + data[2] * 114) // 1000
    # 结合色度简化
    u = data[1] >> 5  # 3-bit
    v = data[2] >> 5  # 3-bit
    return (y & 0xF8) | (u >> 2) | (v << 3)


# 换位
def enhanced_rotated_hash(data):
    r, g, b = data[0] >> 4, data[1] >> 4, data[2] >> 4  # 4-bit压缩
    # 多重异或+位移扩散
    hash_r = (r << 4) ^ (g << 2) ^ b
    hash_g = (g << 4) ^ (b << 2) ^ r
    hash_b = (b << 4) ^ (r << 2) ^ g
    return (hash_r + hash_g * 3 + hash_b * 5) & 0xFF


# 简单哈希法
with Image.open("1.png").convert('RGB') as img:
    width, height = img.size
    pixels = list(img.getdata())
    print(f"尺寸: {width}x{height}")
    print(f"像素数据: {pixels[:10]} ...")

image_set = set([simple_hash_unrolled(bytes(i)) for i in pixels])
print("压缩数量:", len(image_set))
print("压缩哈希:", image_set)
image_hash = [simple_hash_unrolled(bytes(i)) for i in pixels]

hash_map = {key: (0, 0, 0) for key in image_set}
# 全部哈希遍历映射字典
for s in image_set:
    hash_map[s] = pixels[image_hash.index(s)]  # 字典赋值

new_image = [hash_map.get(x, x) for x in image_hash]
# RGB模式
new_img = Image.new('RGB', (width, height))
# 按行填充
new_img.putdata(new_image)
# 保存为PNG文件
new_img.save('2.png', 'PNG')

import numpy as np
from skimage.metrics import structural_similarity as ssim


def calculate_psnr(original_img: Image.Image, compressed_img: Image.Image) -> float:
    """计算两张图像之间的PSNR值"""
    # 将图像转换为NumPy数组
    original = np.array(original_img).astype(np.float64)
    compressed = np.array(compressed_img).astype(np.float64)

    # 确保图像尺寸相同
    if original.shape != compressed.shape:
        raise ValueError("两张图像的尺寸必须相同")

    # 计算MSE(均方误差)
    mse = np.mean((original - compressed) ** 2)

    # 避免除零错误
    if mse == 0:
        return float('inf')

    # 计算PSNR(假设像素值范围为0-255)
    max_pixel = 255.0
    psnr = 20 * np.log10(max_pixel / np.sqrt(mse))

    return psnr


def calculate_ssim(original_img: Image.Image, compressed_img: Image.Image) -> float:
    """计算两张图像之间的SSIM值"""
    # 将图像转换为NumPy数组
    original = np.array(original_img).astype(np.float64)
    compressed = np.array(compressed_img).astype(np.float64)

    # 确保图像尺寸相同
    if original.shape != compressed.shape:
        raise ValueError("两张图像的尺寸必须相同")

    # 如果是彩色图像,分别计算每个通道的SSIM并取平均
    if len(original.shape) == 3 and original.shape[2] == 3:  # RGB图像
        ssim_values = []
        for i in range(3):  # 分别计算R、G、B通道
            ssim_val = ssim(original[:, :, i], compressed[:, :, i],
                            data_range=compressed[:, :, i].max() - compressed[:, :, i].min())
            ssim_values.append(ssim_val)
        return np.mean(ssim_values)
    else:  # 灰度图像
        return ssim(original, compressed,
                    data_range=compressed.max() - compressed.min())


# 加载图像
original = Image.open("1.png").convert("RGB")
compressed = Image.open("2.png").convert("RGB")

# 计算PSNR和SSIM
psnr_value = calculate_psnr(original, compressed)
ssim_value = calculate_ssim(original, compressed)

print(f"PSNR: {psnr_value:.2f} dB")
print(f"SSIM: {ssim_value:.4f}")

# 替换为你的图片路径
original = "1.png"
compressed = "2.png"
# 获取文件大小(KB)
o_size = os.path.getsize(original) / 1024
c_size = os.path.getsize(compressed) / 1024
# 计算并打印压缩率
ratio = (1 - c_size / o_size) * 100
print(f"原始: {o_size:.2f}KB | 压缩后: {c_size:.2f}KB | 压缩率: {ratio:.2f}%")

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

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

相关文章

基本数据指针的解读-C++

1、引言 笔者认为对于学习指针要弄清楚如下问题基本可以应付大部分的场景&#xff1a; ① 指针是什么&#xff1f; ② 指针的类型是什么&#xff1f; ③ 指针指向的类型是什么&#xff1f; ④ 指针指向了哪里&#xff1f; 2、如何使用指针 使用时的步骤如下&#xff1a; ① …

基于多模态脑电、音频与视觉信号的情感识别算法【Nature核心期刊,EAV:EEG-音频-视频数据集】

简述 理解情感状态对于开发下一代人机交互界面至关重要。社交互动中的人类行为会引发受感知输入影响的心理生理过程。因此&#xff0c;探索大脑功能与人类行为的努力或将推动具有类人特质人工智能模型的发展。这里原作者推出一个多模态情感数据集&#xff0c;包含42名参与者的3…

【QueryServer】dbeaver使用phoenix连接Hbase(轻客户端方式)

一、轻客户端连接方式 (推荐) 演示无认证配置方式, 有认证填入下方有认证参数即可 1, 新建连接 → Hadoop/大数据 → Apache Phoenix 2, 手动配置QueryServer驱动: 填入: “类名”, “URL模版”(注意区分有无认证), “端口号”, (勾选无认证) 类名: org.apache.phoenix…

[9-1] USART串口协议 江协科技学习笔记(13个知识点)

1 2 3 4全双工就是两个数据线&#xff0c;半双工就是一个数据线 5 6 7 8 9 10 TTL&#xff08;Transistor-Transistor Logic&#xff09;电平是一种数字电路中常用的电平标准&#xff0c;它使用晶体管来表示逻辑状态。TTL电平通常指的是5V逻辑电平&#xff0c;其中&#xff1a;…

Oracle基础知识(五)——ROWID ROWNUM

目录 一、ROWID 伪列 二、ROWNUM——限制查询结果集行数 1.ROWNUM使用介绍 2.使用ROWNUM进行分页查询 3.使用ROWNUM查看薪资前五位的员工 4.查询指定条数直接的数据 三、ROWNUM与ROWID不同 一、ROWID 伪列 表中的每一行在数据文件中都有一个物理地址&#xff0c;ROWID…

EMS只是快递那个EMS吗?它跟能源有什么关系?

在刚刚落幕的深圳人工智能终端展上&#xff0c;不少企业展示了与数字能源相关的技术和服务&#xff0c;其中一项关键系统——EMS&#xff08;Energy Management System&#xff0c;能量管理系统&#xff09;频频亮相。这个看似低调的名字&#xff0c;实际上正悄然成为未来能源管…

日志技术-LogBack、Logback快速入门、Logback配置文件、Logback日志级别

一. 日志技术 1. 程序中的日志&#xff0c;是用来记录应用程序的运行信息、状态信息、错误信息等。 2. JUL&#xff1a;(java.util.logging)这是JavaSE平台提供的官方日志框架&#xff0c;也被称为JUL。配置相对简单&#xff0c;但不够灵活&#xff0c;性能较差。 3.Logs4j&…

修改Cinnamon主题

~/.themes/Brunnera-Dark/cinnamon/cinnamon.css 1.修改 Tooltip 圆角大小&#xff0c;边框颜色&#xff0c;背景透明度 #Tooltip { border-radius: 10px; color: rgba(255, 255, 255, 0.8); border: 1px solid rgba(255, 255, 255, 0.6); background-color: rgba(0,…

91.评论日记

2025年5月30日20:27:06 AI画减速器图纸&#xff1f; 呜呜为什么读到机械博士毕业了才有啊 | 新迪数字2025新品发布会 | AI工业软件 | 三维CAD | 国产自主_哔哩哔哩_bilibili

HTML5实现简洁的端午节节日网站源码

HTML5实现简洁的端午节节日网站源码 前言一、设计来源1.1 网站首页界面1.2 端午由来界面1.3 节日活动界面1.4 传统美食界面1.5 民俗文化界面1.6 登录界面1.7 注册界面 二、效果和源码2.1 动态效果2.2 源代码 结束语 HTML5实现简洁的端午节节日网站源码&#xff0c;酷炫的大气简…

Window10+ 安装 go环境

一、 下载 golang 源码&#xff1a; 去官网下载&#xff1a; https://go.dev/dl/ &#xff0c;当前时间&#xff08;2025-05&#xff09;最新版本如下: 二、 首先在指定的磁盘下创建几个文件夹 比如在 E盘创建 software 文件夹 E:\SoftWare,然后在创建如下几个文件夹 E:\S…

一、Sqoop历史发展及原理

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月30日 专栏&#xff1a;Sqoop教程 在大数据时代&#xff0c;数据往往分散存储在各种不同类型的系统中。其中&#xff0c;传统的关系型数据库 (RDBMS) 如 MySQL, Oracle, PostgreSQL 等&#xff0c;仍然承载着大量的关键业务…

React 编译器 RC

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&#…

关于表连接

目录 1.左连接 2.右连接 3.内连接 4.全外连接 5.笛卡尔积 -- 创建表A CREATE TABLE A(PNO VARCHAR2(10) PRIMARY KEY, PAMT NUMBER, A_DATE DATE);-- 向表A插入数据 INSERT INTO A VALUES (01001, 100, TO_DATE(2005-01-01, YYYY-MM-DD)); INSERT INTO A VALUES (010…

【计算机网络】fork()+exec()创建新进程(僵尸进程及孤儿进程)

文章目录 一、基本概念1. fork() 系统调用2. exec() 系列函数 二、典型使用场景1. 创建子进程执行新程序2. 父子进程执行不同代码 三、核心区别与注意事项四、组合使用技巧1. 重定向子进程的输入/输出2. 创建多级子进程 五、常见问题与解决方案僵尸进程&#xff08;Zombie Proc…

Word表格怎样插入自动序号或编号

在Word文档中编辑表格时&#xff0c;经常需要为表格添加序号或编号&#xff0c;可以设置为自动序号或编号&#xff0c;当删除行时&#xff0c;编号会自动变化&#xff0c;不用手工再重新编号。如图所示。 序号数据1数据21300300230030033003004300300 一&#xff0c;建立word表…

无人机仿真环境(3维)附项目git链接

项目概述 随着无人机技术在物流、测绘、应急救援等领域的广泛应用&#xff0c;其自主导航、避障算法、路径规划及多机协同等核心技术的研究需求日益迫切。为降低实地测试成本、提高研发效率&#xff0c;本项目旨在构建一个高精度、可扩展的​​无人机三维虚拟仿真环境​​&…

Python 训练营打卡 Day 30-模块和库的导入

模块和库的导入 1.1标准导入 import mathprint("方式1: 使用 import math") print(f"圆周率π的值: {math.pi}") print(f"2的平方根: {math.sqrt(2)}\n") 1.2从库中导入特定项 from math import pi, sqrtprint("方式2&#xff1a;使用 f…

前端实现图片压缩:基于 HTML5 File API 与 Canvas 的完整方案

在 Web 开发中,处理用户上传的图片时,前端压缩可以有效减少服务器压力并提升上传效率。本文将详细讲解如何通过<input type="file">实现图片上传,结合 Canvas 实现图片压缩,并实时展示压缩前后的图片预览和文件大小对比。 一、核心功能架构 我们将实现以…

【Docker管理工具】部署Docker管理面板DweebUI

【Docker管理工具】部署Docker管理面板DweebUI 一、DweebUI介绍1.1 DweebUI 简介1.2 主要特点1.3 使用场景 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载DweebUI镜像五、…