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

PIL转换numpy数组格式RGB图像为PNG时输出结果异常

问题根源

你遇到的灰度、内容重复问题由两个核心错误导致:

  • 数组维度顺序处理错误:rasterio的read()方法返回的数组默认维度排列为(波段数, 图像高度, 图像宽度),对你的文件来说读取后的shape是(3, 10800, 21600)。直接调用reshape(10800, 21600, 3)只会强行修改数组的形状属性,不会调整像素在内存中的排列顺序,最终会把不同波段、不同位置的像素打乱拼接,直接造成内容重复、色彩错位显示为灰度。
  • 未做像素值范围适配:很多TIFF文件(尤其是遥感类GeoTIFF)的像素存储位深不是8位,可能是16位、32位,数值范围也不是PNG要求的0-255区间,直接强转np.uint8会出现数值截断、色彩异常。
修正代码
import rasterio
import numpy as np
from PIL import Image

with rasterio.open("world.tif") as dataset:
    window = rasterio.windows.Window(0, 0, 21600, 10800)
    # 读取窗口内数据,输出维度为(波段, 高度, 宽度)
    raster_data = dataset.read(window=window)

# 调整维度顺序为PIL要求的(高度, 宽度, 波段)
rgb_data = np.transpose(raster_data, (1, 2, 0))

# 适配非8位源数据,将像素值线性拉伸到0-255区间
if rgb_data.dtype != np.uint8:
    val_min, val_max = rgb_data.min(), rgb_data.max()
    rgb_data = ((rgb_data - val_min) / (val_max - val_min) * 255).astype(np.uint8)

# 导出PNG
output_img = Image.fromarray(rgb_data, "RGB")
output_img.save("out.png")
补充说明
  • 如果你的TIFF包含4个波段(带Alpha透明通道),可以在转置前先截取前3个RGB波段:raster_data = raster_data[:3, :, :],避免通道数不匹配报错。
  • 21600×10800属于超大幅面图像,如果保存时出现内存不足,可以在save方法中添加参数compress_level=6启用压缩降低内存占用,也可以根据需求分块导出。
  • 不要用reshape直接调整带通道维度的数组形状,这类维度顺序调换操作必须用np.transpose或者np.swapaxes完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:01:07