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

基于PIL模仿Trichromy为黑白照片上色失败,求解决方法

问题分析与解决方案

核心问题

你当前的做法只是给灰度原图添加了透明度后直接叠加,三个灰度半透明图层叠加后依然是灰度效果——因为每个图层没有携带对应的色彩通道信息,本质还是灰度图的透明度混合,而非三原色通道的合成。

老式Trichromy工艺的核心是:将黑白照片的亮度信息分别分配到红、绿、蓝三个色彩通道,再将这三个单通道色彩图层叠加,从而还原彩色效果。

修正步骤

  1. 先将原图转为灰度图,确保亮度信息统一
  2. 为每个色彩通道创建独立的RGB图层:
    • 红色图层:R通道保留灰度值,G、B通道设为0
    • 绿色图层:G通道保留灰度值,R、B通道设为0
    • 蓝色图层:B通道保留灰度值,R、G通道设为0
  3. 为每个色彩图层添加alpha通道,透明度设为round(255/3)
  4. 使用alpha_composite依次叠加三个色彩图层

修正后的代码示例

from PIL import Image

def color_photo(input_path, output_path):
    # 打开原图并转为灰度图
    with Image.open(input_path) as img:
        gray_img = img.convert("L")
        width, height = gray_img.size
        alpha_val = round(255/3)
        
        # 生成红色通道图层
        red_layer = Image.new("RGBA", (width, height))
        for x in range(width):
            for y in range(height):
                gray_val = gray_img.getpixel((x, y))
                red_layer.putpixel((x, y), (gray_val, 0, 0, alpha_val))
        
        # 生成绿色通道图层
        green_layer = Image.new("RGBA", (width, height))
        for x in range(width):
            for y in range(height):
                gray_val = gray_img.getpixel((x, y))
                green_layer.putpixel((x, y), (0, gray_val, 0, alpha_val))
        
        # 生成蓝色通道图层
        blue_layer = Image.new("RGBA", (width, height))
        for x in range(width):
            for y in range(height):
                gray_val = gray_img.getpixel((x, y))
                blue_layer.putpixel((x, y), (0, 0, gray_val, alpha_val))
        
        # 叠加图层并保存
        result = Image.alpha_composite(red_layer, green_layer)
        result = Image.alpha_composite(result, blue_layer)
        result.convert("RGB").save(output_path)

效率优化版本

如果觉得逐像素处理速度慢,可以改用Pillow的通道合并API提升效率:

from PIL import Image

def color_photo(input_path, output_path):
    with Image.open(input_path) as img:
        gray_img = img.convert("L")
        alpha_val = round(255/3)
        
        # 通过通道合并快速生成单色彩图层
        red_layer = Image.merge(
            "RGBA",
            (gray_img, Image.new("L", gray_img.size, 0), Image.new("L", gray_img.size, 0), Image.new("L", gray_img.size, alpha_val))
        )
        green_layer = Image.merge(
            "RGBA",
            (Image.new("L", gray_img.size, 0), gray_img, Image.new("L", gray_img.size, 0), Image.new("L", gray_img.size, alpha_val))
        )
        blue_layer = Image.merge(
            "RGBA",
            (Image.new("L", gray_img.size, 0), Image.new("L", gray_img.size, 0), gray_img, Image.new("L", gray_img.size, alpha_val))
        )
        
        # 叠加并保存结果
        result = Image.alpha_composite(Image.alpha_composite(red_layer, green_layer), blue_layer)
        result.convert("RGB").save(output_path)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:50:39