我使用加载我的纹理
Texture2D.FromFile()
Run Code Online (Sandbox Code Playgroud)
然后用它们画出来
spriteBatch.Draw()
Run Code Online (Sandbox Code Playgroud)
但重点是:我想将图像的某些颜色更改为另一种颜色.所以我的问题:
如何将图像的单色更改为另一种颜色(例如蓝色到红色).
事实上,我真正想做的是将一组颜色改为另一组颜色.例如红色和类似色调,红色到蓝色,类似色调,蓝色.例如,您可以在Corel PHOTO-PAINT("替换颜色")中执行此操作.
请记住,我是XNA的初学者.最好的问候,杰克
伙计们,非常感谢您的帮助.Callum的回答确实非常有用.但我想知道是否有内置函数来解决我的第二个问题,因为编写自己的函数可能非常耗时.我认为,这种功能可能非常有用.就像是:
color.SetNewColor(Color color_from, Color color_to, int range)
Run Code Online (Sandbox Code Playgroud)
正如我之前所说的那样,这种功能是用Corel PHOTO-PAINT构建的.为了更好地解释它,这里是我正在谈论的例子:
所以,我只设置color_from,color_to和range.我认为它的作用是这样的:它检查图像的每种颜色,如果它在color_from的范围内,它会在color_to的色调中变为足够的颜色.
Cal*_*ers 11
我猜你的意思是改变个别像素?在这种情况下,使用类的GetData()和SetData()方法Texture2D.
例如,您可以通过执行以下操作获取包含各个像素颜色的数组:
// Assume you have a Texture2D called texture
Color[] data = new Color[texture.Width * texture.Height];
texutre.GetData(data);
// You now have a packed array of Colors.
// So, change the 3rd pixel from the right which is the 4th pixel from the top do:
data[4*texture.Width+3] = Color.Red;
// Once you have finished changing data, set it back to the texture:
texture.SetData(data);
Run Code Online (Sandbox Code Playgroud)
请注意,您可以使用其他重载GetData()来仅选择一个部分.
因此,要将指定颜色的每个像素替换为另一种颜色:
// Assume you have a Texture2D called texture, Colors called colorFrom, colorTo
Color[] data = new Color[texture.Width * texture.Height];
texutre.GetData(data);
for(int i = 0; i < data.Length; i++)
if(data[i] == colorFrom)
data[i] = colorTo;
texture.SetData(data);
Run Code Online (Sandbox Code Playgroud)
要查看色调是否相似,请尝试以下方法:
private bool IsSimilar(Color original, Color test, int redDelta, int blueDelta, int greenDelta)
{
return Math.Abs(original.R - test.R) < redDelta && Math.Abs(original.G - test.G) < greenDelta && Math.Abs(original.B - test.B) < blueDelta;
}
Run Code Online (Sandbox Code Playgroud)
其中*delta是您要接受的每个颜色通道的更改容差.
要回答您的编辑,没有内置功能,但您可以使用上述两个部分的混合思路:
Color[] data = new Color[texture.Width * texture.Height];
texutre.GetData(data);
for(int i = 0; i < data.Length; i++)
if(IsSimilar(data[i], colorFrom, range, range, range))
data[i] = colorTo;
texture.SetData(data);
Run Code Online (Sandbox Code Playgroud)
使用 GetData 和 SetData 在 GPU 和 CPU 之间移动数据是一项昂贵的操作。如果颜色数量有限,您可以在渲染到屏幕时使用像素着色器效果。您可以将效果传递给 SpriteBatch.Begin:
sampler2D input : register(s0);
/// <summary>The color used to tint the input.</summary>
/// <defaultValue>White</defaultValue>
float4 FromColor : register(C0);
/// <summary>The color used to tint the input.</summary>
/// <defaultValue>Red</defaultValue>
float4 ToColor : register(C1);
/// <summary>Explain the purpose of this variable.</summary>
/// <minValue>05/minValue>
/// <maxValue>10</maxValue>
/// <defaultValue>3.5</defaultValue>
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 Color;
Color= tex2D(input , uv.xy);
if (Color.r == FromColor.r && Color.g == FromColor.g && Color.b == FromColor.b)
return ToColor;
return Color;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 main();
}
}
Run Code Online (Sandbox Code Playgroud)
在 LoadContent 方法中创建效果:
colorSwapEffect = Content.Load<Effect>(@"Effects\ColorSwap");
colorSwapEffect.Parameters["FromColor"].SetValue(Color.White);
colorSwapEffect.Parameters["ToColor"].SetValue(Color.Red);
Run Code Online (Sandbox Code Playgroud)
并将效果传递给您对 SpriteBatch.Begin() 的调用:
sprite.Begin(0, BlendState.Opaque, SamplerState.PointWrap,
DepthStencilState.Default, RasterizerState.CullNone, colorSwapEffect);
Run Code Online (Sandbox Code Playgroud)
对于您真正想做的事情,您可以更轻松地交换红色和蓝色通道。将像素着色器的 main() 函数更改为此,交换 b(蓝色)和 r(红色):
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 Color;
Color= tex2D(input , uv.xy);
return float4(Color.b, Color.g, Color.r, Color.a);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13389 次 |
| 最近记录: |