在c#中将灰度部分透明图像转换为单一颜色
Convert grayscale partially transparent image to a single color in c#
我正在尝试创建一个函数,该函数采用灰度图像和颜色,并使用该颜色阴影为灰度图像着色,但保持灰度图像的阴影级别。该函数也不应为图像的透明部分着色。我有多个图层(多个 png),我稍后会合并,只需要为某些图层着色。我环顾四周,发现了类似的东西,但并不完全是我需要的。我知道如何在前端的 HTML5 中为使用 Canvas 的用户做到这一点,但我需要一种方法来在后端使用我猜测使用解锁位图内存调用的手动方法或颜色矩阵 class。任何人都可以帮助我,图形不是我最强的领域,但我正在慢慢学习。请参阅下面的函数,了解我在 javascript 中所做的 C# 中所需的内容。做隐藏的 canvas 东西并不重要,因为我正在做这个服务器端以保存到 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);
};
这应该可以完成工作:
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
;
它开始工作了,首先添加红色,然后添加更多红色和一些蓝色:
透明像素不受影响。
有关 ColorMatrix
here is a really nice intro!
的更多信息
作为一个有趣的项目,我将已知的颜色应用到一张已知的脸上:
我正在尝试创建一个函数,该函数采用灰度图像和颜色,并使用该颜色阴影为灰度图像着色,但保持灰度图像的阴影级别。该函数也不应为图像的透明部分着色。我有多个图层(多个 png),我稍后会合并,只需要为某些图层着色。我环顾四周,发现了类似的东西,但并不完全是我需要的。我知道如何在前端的 HTML5 中为使用 Canvas 的用户做到这一点,但我需要一种方法来在后端使用我猜测使用解锁位图内存调用的手动方法或颜色矩阵 class。任何人都可以帮助我,图形不是我最强的领域,但我正在慢慢学习。请参阅下面的函数,了解我在 javascript 中所做的 C# 中所需的内容。做隐藏的 canvas 东西并不重要,因为我正在做这个服务器端以保存到 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);
};
这应该可以完成工作:
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
;
它开始工作了,首先添加红色,然后添加更多红色和一些蓝色:
透明像素不受影响。
有关 ColorMatrix
here is a really nice intro!
作为一个有趣的项目,我将已知的颜色应用到一张已知的脸上: