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

如何复现Photoshop亮度提升操作?求对应数学公式及C#实现

模拟Photoshop「亮度/对比度」亮度提升的C#实现

我已经掌握通过HSV提升颜色Value值的方法,但这种方式是对所有色调统一增幅,容易导致颜色泛白;而Photoshop的亮度操作会差异化处理不同色调,效果更自然。现在需要基于输入RGB颜色和亮度增量,通过数学公式计算出调整后的RGB颜色(示例中亮度增量为150)。

以下是基础代码框架:

// ARGB color
public Color m_color = new Color(255, 255, 0, 255);

public Color IncreaseBrightness(Color colorToModify, float brightnessAmount)
{
    Color newColor = colorToModify;

    // 使用Photoshop公式按brightnessAmount提升newColor的RGB亮度(待实现)

    return newColor;
}

// 调用示例,需达到示例图片中的效果
IncreaseBrightness(m_color, 150f);

实现逻辑

Photoshop的「亮度/对比度」调整并非对RGB通道做线性增益,而是基于sRGB色彩空间与线性光转换的非线性映射,核心是对暗部区域的增益大于高光区域,避免高光过曝泛白。完整步骤如下:

  1. sRGB转线性RGB:将0-255的通道值转换为线性光空间,这是PS调整的基础
  2. 应用亮度调整公式:根据亮度增量对线性光值做差异化增益
  3. 线性RGB转回sRGB:将调整后的线性值转换回标准sRGB范围

关键公式

  • sRGB转线性RGB:

    linear = norm <= 0.04045 ? norm / 12.92 : pow((norm + 0.055)/1.055, 2.4)
    

    其中norm是通道值归一化到0-1的结果

  • 亮度调整(适配PS滑块范围[-100,100]):

    if brightness >= 0:
        adjusted_linear = linear + (1 - linear) * (brightness / 100)
    else:
        adjusted_linear = linear * (1 + brightness / 100)
    
  • 线性RGB转回sRGB:

    norm = adjusted_linear <= 0.0031308 ? adjusted_linear * 12.92 : 1.055 * pow(adjusted_linear, 1/2.4) - 0.055
    

完整C#代码实现

using System;
using System.Drawing;

public class BrightnessAdjuster
{
    public Color m_color = Color.FromArgb(255, 255, 0, 255);

    public Color IncreaseBrightness(Color colorToModify, float brightnessAmount)
    {
        // 将输入的亮度增量(示例150)转换为PS滑块的[-100,100]范围
        float psBrightness = brightnessAmount - 100f;

        // 处理红色通道
        byte rAdjusted = AdjustChannel(colorToModify.R, psBrightness);
        // 处理绿色通道
        byte gAdjusted = AdjustChannel(colorToModify.G, psBrightness);
        // 处理蓝色通道
        byte bAdjusted = AdjustChannel(colorToModify.B, psBrightness);

        return Color.FromArgb(colorToModify.A, rAdjusted, gAdjusted, bAdjusted);
    }

    private byte AdjustChannel(byte channelValue, float brightness)
    {
        // 归一化到0-1
        float norm = channelValue / 255f;
        // 转线性光
        float linear = sRgbToLinear(norm);
        // 应用亮度调整
        float adjustedLinear = ApplyBrightness(linear, brightness);
        // 转回sRGB并转为字节
        return linearToSRgb(adjustedLinear);
    }

    private float sRgbToLinear(float norm)
    {
        return norm <= 0.04045f ? norm / 12.92f : (float)Math.Pow((norm + 0.055f) / 1.055f, 2.4f);
    }

    private byte linearToSRgb(float linear)
    {
        float norm = linear <= 0.0031308f ? linear * 12.92f : (float)(1.055f * Math.Pow(linear, 1 / 2.4f) - 0.055f);
        // 限制在0-1范围内,避免溢出
        norm = Math.Clamp(norm, 0f, 1f);
        return (byte)Math.Round(norm * 255f);
    }

    private float ApplyBrightness(float linearValue, float brightness)
    {
        float adjusted;
        if (brightness >= 0)
        {
            // 提升亮度:暗部增益更大
            adjusted = linearValue + (1 - linearValue) * (brightness / 100f);
        }
        else
        {
            // 降低亮度:高光衰减更小
            adjusted = linearValue * (1 + brightness / 100f);
        }
        return Math.Clamp(adjusted, 0f, 1f);
    }

    // 测试调用
    public void RunTest()
    {
        Color adjustedColor = IncreaseBrightness(m_color, 150f);
        // 输出调整后的颜色值,应匹配PS中亮度+50的效果
        Console.WriteLine($"调整后颜色:A={adjustedColor.A}, R={adjustedColor.R}, G={adjustedColor.G}, B={adjustedColor.B}");
    }
}

说明

  • 代码中brightnessAmount参数若传入150,对应Photoshop亮度滑块调至+50的效果(PS滑块范围为-100到+100,这里将0映射为-100,200映射为+100),可根据需求调整转换逻辑
  • 通过sRGB与线性光的转换,完全模拟PS的色彩空间调整逻辑,解决HSV Value提升导致的泛白问题
  • 所有计算都做了区间限制,确保最终RGB值在0-255的有效范围内

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:25:01