You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何快速将超大NumPy数组保存为无损TIFF图像?

解决方案:多核加速超大TIFF无损压缩

针对30000×30000像素级RGB图像的无损TIFF保存瓶颈,以下是几个支持多核CPU加速的Python方案,直接解决单核压缩效率低下的问题:

1. PyVips(推荐:开箱即用的多核支持)

PyVips基于libvips库,天生支持多核并行处理,大图像压缩速度、内存占用表现均优于传统库。

安装

pip install pyvips

示例代码

import pyvips
import numpy as np
import time

arr = np.random.default_rng().integers(0, 255, size=(30000,30000,3), endpoint=True, dtype=np.uint8)

# 将NumPy数组转为PyVips格式(调整维度顺序适配PyVips的WHC存储)
vips_img = pyvips.Image.new_from_memory(
    arr.transpose((1, 0, 2)).tobytes(),
    arr.shape[1], arr.shape[0], 3, 'uchar'
)

st = time.time()
# 启用deflate压缩+分块存储,自动利用多核
vips_img.save(
    'test_pyvips.tiff',
    compression='deflate',
    tile=True,
    tile_width=256,
    tile_height=256
)
print(f"PyVips took {time.time()-st} s")

关键说明

  • libvips会自动调度所有CPU核心参与压缩,速度比单核库提升数倍
  • 分块(tile)存储优化大图像读写性能,同时降低内存压力
  • 无需额外配置,开箱即用

2. tifffile + imagecodecs(多核压缩后端)

通过imagecodecs提供的多核压缩算法,让tifffile实现并行压缩。

安装

pip install tifffile imagecodecs

示例代码

import tifffile
import numpy as np
import time

arr = np.random.default_rng().integers(0, 255, size=(30000,30000,3), endpoint=True, dtype=np.uint8)

st = time.time()
tifffile.imwrite(
    'test_tifffile_multicore.tiff',
    arr,
    compression='zlib',
    compressionargs={'level': 5, 'workers': 6},  # workers设为CPU物理核心数
    predictor=True,
    tile=(256, 256)
)
print(f"Tifffile (multicore) took {time.time()-st} s")

关键说明

  • imagecodecs提供了多核优化的zlib/lzma等压缩实现,tifffile会自动调用
  • workers参数指定使用的核心数,建议匹配CPU物理核心数(如5600X设为6)
  • 分块存储进一步提升压缩效率

3. 手动多进程分片压缩(高自定义场景)

如果需要完全自定义压缩逻辑,可手动拆分图像块,用多进程并行压缩后合并。

示例代码

import numpy as np
import tifffile
import time
import os
from multiprocessing import Pool

def compress_block(args):
    block, block_idx = args
    temp_path = f'temp_block_{block_idx}.tiff'
    tifffile.imwrite(temp_path, block, compression='zlib', level=5, predictor=True)
    return temp_path

if __name__ == '__main__':
    arr = np.random.default_rng().integers(0, 255, size=(30000,30000,3), endpoint=True, dtype=np.uint8)
    
    # 按CPU核心数拆分垂直块(5600X为6核)
    core_count = 6
    block_height = arr.shape[0] // core_count
    blocks = [arr[i*block_height:(i+1)*block_height, :, :] for i in range(core_count)]
    if arr.shape[0] % core_count != 0:
        blocks.append(arr[core_count*block_height:, :, :])
    
    st = time.time()
    # 多进程压缩块
    with Pool(processes=core_count) as pool:
        temp_files = pool.map(compress_block, [(block, i) for i, block in enumerate(blocks)])
    
    # 合并块为单TIFF
    with tifffile.TiffWriter('test_multiprocess.tiff') as tif:
        for temp_file in temp_files:
            with tifffile.TiffFile(temp_file) as tf:
                tif.write(tf.pages[0].asarray(), compression='zlib', predictor=True)
            os.remove(temp_file)
    
    print(f"Multiprocess took {time.time()-st} s")

关键说明

  • 适合需要定制压缩策略的场景
  • 需手动处理块拆分、临时文件管理和合并逻辑
  • 可灵活调整块大小和进程数

补充提示

  • Intel vs AMD速度差异:部分传统库的压缩实现对Intel指令集(如AVX2)有针对性优化,使用上述多核方案可抹平这种硬件差异
  • 压缩算法选择:deflate(zlib)在速度和压缩率间平衡最优,lzma压缩率更高但速度稍慢

内容的提问来源于stack exchange,提问作者Raphael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:20:38