基于PIL模仿Trichromy为黑白照片上色失败,求解决方法
问题分析与解决方案
核心问题
你当前的做法只是给灰度原图添加了透明度后直接叠加,三个灰度半透明图层叠加后依然是灰度效果——因为每个图层没有携带对应的色彩通道信息,本质还是灰度图的透明度混合,而非三原色通道的合成。
老式Trichromy工艺的核心是:将黑白照片的亮度信息分别分配到红、绿、蓝三个色彩通道,再将这三个单通道色彩图层叠加,从而还原彩色效果。
修正步骤
- 先将原图转为灰度图,确保亮度信息统一
- 为每个色彩通道创建独立的RGB图层:
- 红色图层:R通道保留灰度值,G、B通道设为0
- 绿色图层:G通道保留灰度值,R、B通道设为0
- 蓝色图层:B通道保留灰度值,R、G通道设为0
- 为每个色彩图层添加alpha通道,透明度设为
round(255/3) - 使用
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
相关产品推荐
相关产品推荐

