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

能否通过单个ColorMatrix同时调整Bitmap的色相、饱和度、亮度与透明度?

单次重绘Bitmap实现色相、饱和度、亮度与透明度同步调整

我希望通过单次重绘Bitmap,同时调整其色相、饱和度、亮度与透明度。目前已有一个可调整图像饱和度、亮度和透明度的函数,运行正常:

public static void AdjustImageAttributes(Image image, float brightness, float saturation, float transparency)
{
    // Luminance vector for linear RGB
    const float rwgt = 0.3086f;
    const float gwgt = 0.6094f;
    const float bwgt = 0.0820f;

    // Create a new color matrix
    ColorMatrix colorMatrix = new ColorMatrix();

    // Adjust saturation
    float baseSat = 1.0f - saturation;
    colorMatrix[0, 0] = baseSat * rwgt + saturation;
    colorMatrix[0, 1] = baseSat * rwgt;
    colorMatrix[0, 2] = baseSat * rwgt;
    colorMatrix[1, 0] = baseSat * gwgt;
    colorMatrix[1, 1] = baseSat * gwgt + saturation;
    colorMatrix[1, 2] = baseSat * gwgt;
    colorMatrix[2, 0] = baseSat * bwgt;
    colorMatrix[2, 1] = baseSat * bwgt;
    colorMatrix[2, 2] = baseSat * bwgt + saturation;

    // Adjust brightness
    float adjustedBrightness = brightness - 1f;
    colorMatrix[4, 0] = adjustedBrightness;
    colorMatrix[4, 1] = adjustedBrightness;
    colorMatrix[4, 2] = adjustedBrightness;

    colorMatrix[3, 3] = transparency;

    // Create image attributes
    ImageAttributes imageAttributes = new ImageAttributes();
    imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

    // Draw the image with the new color matrix
    using (Graphics g = Graphics.FromImage(image))
    {
        g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height),
        0, 0, image.Width, image.Height,
        GraphicsUnit.Pixel, imageAttributes);
    }
}

另外,我还有一个可生成指定色相旋转ColorMatrix的函数:

ColorMatrix GetHueShiftColorMax(Single hueShiftDegrees)
{
    /* Return the matrix
    
        A00  A01  A02  0  0
        A10  A11  A12  0  0
        A20  A21  A22  0  0
          0    0    0  1  0
          0    0    0  0  1
    */
    Single theta = hueShiftDegrees/360 * 2*pi; //Degrees --> Radians
    Single c = cos(theta);
    Single s = sin(theta);

    Single A00 = 0.213 + 0.787*c - 0.213*s;
    Single A01 = 0.213 - 0.213*c + 0.413*s;
    Single A02 = 0.213 - 0.213*c - 0.787*s;

    Single A10 = 0.715 - 0.715*c - 0.715*s;
    Single A11 = 0.715 + 0.285*c + 0.140*s;
    Single A12 = 0.715 - 0.715*c + 0.715*s;

    Single A20 = 0.072 - 0.072*c + 0.928*s;
    Single A21 = 0.072 - 0.072*c - 0.283*s;
    Single A22 = 0.072 + 0.928*c + 0.072*s;

    ColorMatrix cm = new ColorMatrix(
          ( A00, A01, A02,  0,  0 ),
          ( A10, A11, A12,  0,  0 ),
          ( A20, A21, A22,  0,  0 ),
          (   0,   0,   0,  0,  0 ),
          (   0,   0,   0,  0,  1 )
    )

    return cm;
}

现在我有两个独立的ColorMatrix,虽然可以先调用第一个函数重绘图像,再调用色相调整函数再次重绘,但这显得冗余。我认为应该可以将两个矩阵合并为一个,从而通过单次重绘完成所有调整,但相关数学原理超出我的理解范围,不知从何入手。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:47:12