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

如何防止Pillow修改TIFF像素值时将uint16转换为uint8?

解决16位RGBA TIFF像素修改时的格式降级问题

问题根源

你的脚本存在三个核心问题:

  • 逐像素调用putpixel会触发PIL的隐式图像模式转换,把原本的16位(RGBA;16)图像转成8位(RGBA),直接导致画质损失和文件大小变化。
  • 两次嵌套循环完全冗余,第一次循环仅读取像素值却未做任何处理,且逐像素操作效率极低,不适合大尺寸TIFF文件。
  • 保存时未指定TIFF的位深度参数,PIL默认以8位格式输出。

解决方案:用Numpy批量处理像素(保持uint16格式)

使用Numpy直接操作图像数组,既能严格保留16位数据类型,又能大幅提升处理效率,彻底避免模式转换问题。

import numpy as np
from PIL import Image

# 打开目标TIFF,保留原图像模式
with Image.open('dtmortho-000016_000052-14cm.tif') as im:
    # 将图像转换为uint16类型的Numpy数组,严格继承原数据格式
    img_array = np.array(im, dtype=np.uint16)
    
    # 匹配RGB为(0,0,0)的像素,替换为(5,5,5),保留原Alpha通道
    black_pixels = (img_array[..., 0] == 0) & (img_array[..., 1] == 0) & (img_array[..., 2] == 0)
    img_array[black_pixels, :3] = [5, 5, 5]
    
    # 匹配RGB为(255,255,255)的像素,替换为(250,250,250),保留原Alpha通道
    white_pixels = (img_array[..., 0] == 255) & (img_array[..., 1] == 255) & (img_array[..., 2] == 255)
    img_array[white_pixels, :3] = [250, 250, 250]
    
    # 将修改后的数组转回PIL图像,沿用原图像的16位模式
    modified_img = Image.fromarray(img_array, mode=im.mode)
    
    # 保存时强制指定TIFF格式,确保所有通道保留16位深度
    modified_img.save('output.tif', format='TIFF', save_all=True)

关键细节说明

  1. 锁死数据类型:np.array(im, dtype=np.uint16)确保数组严格继承原图像的16位无符号整数格式,杜绝隐式类型转换。
  2. 批量高效操作:通过Numpy的布尔索引批量匹配目标像素,比逐像素循环效率高数十倍,尤其适合大尺寸TIFF文件。
  3. 正确保存参数:save_all=True确保TIFF的所有通道(包括Alpha)都按原格式保存,format='TIFF'避免PIL自动选择其他格式降级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:15:30