在c#中将灰度部分透明图像转换为单色

时间:2016-09-25 23:45:58

标签: c# graphics bitmap gdi+

我正在尝试使用该色调创建一个采用灰度图像和颜色并为灰度图像着色的函数,但保留灰度图像的阴影级别。该功能也不应该为图像的透明部分着色。我有多个图层(多个png' s)我稍后会合并,只需要为某些图层着色。我环顾四周,发现了类似的东西,但并不是我需要的东西。我知道如何在前端为使用Canvas的用户在HTML5中进行操作,但我需要一种方法在后端实现相同的功能我猜测使用解锁位图内存调用的手动方法或ColorMatrix类。任何人都可以帮助我,图形不是我最强的领域,但我正在慢慢学习。请参阅下面的函数,了解我在C#中使用javascript所需的内容。做隐藏的画布并不重要,因为我正在这个服务器端保存到PNG文件......

function drawImage(imageObj, color) {
    var hidden_canvas = document.createElement("canvas");
    hidden_canvas.width = imageObj.width;
    hidden_canvas.height = imageObj.height;
    var hidden_context = hidden_canvas.getContext("2d");

    // draw the image on the hidden canvas
    hidden_context.drawImage(imageObj, 0, 0);

    if (color !== undefined) {
        var imageData = hidden_context.getImageData(0, 0, imageObj.width, imageObj.height);
        var data = imageData.data;

        for (var i = 0; i < data.length; i += 4) {
            var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];

            //red
            data[i] = brightness + color.R;
            //green
            data[i + 1] = brightness + color.G;
            //blue
            data[i + 2] = brightness + color.B;
        }

        //overwrite original image
        hidden_context.putImageData(imageData, 0, 0);
    }

    var canvas = document.getElementById('card');
    var context = canvas.getContext('2d');
    context.drawImage(hidden_canvas, 0, 0);
};

1 个答案:

答案 0 :(得分:1)

这应该做的工作:

public static Bitmap MakeChromaChange(Bitmap bmp0, Color tCol, float gamma)
{
    Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height);

    using (Graphics g = Graphics.FromImage(bmp1))
    {
        float f = (tCol.R + tCol.G + tCol.B) / 765f;
        float tr = tCol.R / 255f - f;
        float tg = tCol.G / 255f - f;
        float tb = tCol.B / 255f - f;

        ColorMatrix colorMatrix = new ColorMatrix(new float[][]
        {  new float[] {1f + tr, 0, 0, 0, 0},
           new float[] {0, 1f + tg, 0, 0, 0},
           new float[] {0, 0, 1f + tb, 0, 0},
           new float[] {0, 0, 0, 1, 0},
           new float[] {0, 0, 0, 0, 1}  });

        ImageAttributes attributes = new ImageAttributes();
        attributes.SetGamma(gamma);
        attributes.SetColorMatrix(colorMatrix);

        g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height),
            0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes);
    }
    return bmp1;
}

请注意,我保留了伽玛参数;如果您不需要,请将值保持为1f;

在这里工作,先添加红色,然后添加更多红色和蓝色:

enter image description here enter image description here enter image description here

透明像素不受影响。

有关ColorMatrix的详情,请点击really nice intro

作为一个有趣的项目,我将已知颜色应用于已知面部:

enter image description here