问题描述
我正在尝试创建一个采用灰度图像和颜色的函数,并使用该颜色阴影对灰度图像着色,但保留灰度图像的着色级别。该功能也不应该为图像的透明部分着色。我有多个图层(多个PNG的),我会稍后合并,只需要对某些图层进行着色。我环顾四周,发现了类似的东西,但并不完全符合我的需求。我知道如何在HTML5前端为使用Canvas的用户做到这一点,但我需要一种方法在后端实现同样的事情,我猜测是使用解锁位图内存调用或ColorMatrix类的手动方法。任何人都可以帮助我,图形并不是我最强的领域,但我正在慢慢学习。查看下面的函数,了解我在C#中需要的内容。做隐藏的画布的东西并不重要,因为我正在做这个服务器端保存为PNG文件...
函数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);
//在隐藏的画布上绘制图像
hidden_context.drawImage(imageObj,0,0);
if(color!== undefined){
var imageData = hidden_context.getImageData(0,0,imageObj.width,imageObj.height);
var data = imageData.data; (var i = 0; i 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;
//蓝色
数据[i + 2] =亮度+色彩.B;
}
//覆盖原始图片
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)
{
位图bmp1 =新位图(bmp0。宽度,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();
属性.SetGamma(gamma);
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(bmp0,new Rectangle(0,0,bmp0.Width,bmp0.Height),
0,0,bmp0.Width,bmp0.Height,GraphicsUnit.Pixel,属性);
}
return bmp1;
}
请注意,我保留了一个gamma参数;如果您不需要它,请将值保持在 1f
;
在此工作中,将第一个红色然后更红和一些蓝色:
透明像素不受影响。 有关
I am trying to create a function that takes a gray scale image and a color and colors the gray scale image using that color shade but keeps the shading levels of the gray scale image. The function also should not color the transparent parts of the image. I have multiple layers (multiple png's) I will be combining later and only need to color certain layers. I have looked around and found similar things but not quite what I need. I know how to do it in HTML5 on front end for the user using Canvas but I need a way to achieve same thing on the backend using I am guessing either a manual method using unlocked bitmap memory calls or a ColorMatrix class. Can anyone help me, graphics aren't my strongest area but I am slowly learning. See the function below for what I need in C# that I did in javascript. Doing the hidden canvas stuff isn't as important because I am doing this server side for saving to PNG file...
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);
};
This should do the job:
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;
}
Note that I kept a gamma parameter; if you don't need it keep the value at 1f
;
Here it is at work, adding first red then more red and some blue :
Transparent pixels are not affected.
For more on ColorMatrix
here is a really nice intro!
As a fun project I applied the known colors to a known face:
这篇关于在c#中将灰度部分透明的图像转换为单一颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!