我正在尝试根据用户输入显示纹理的单独R,G,B和A通道。我正在使用Image类来显示具有alpha通道的纹理。这些纹理加载到BitmapSource对象中,格式为Bgra32。问题在于,当我将Image的Source设置为BitmapSource时,如果我显示R,G或B通道的任意组合,我总是得到与alpha值预先相乘的像素。我编写了一个非常简单的着色器,预编译它,并使用ShaderEffect类分配给Image的Effect属性,以便分离和显示单独的通道,但显然,在WPF预乘之后,着色器被赋予纹理。纹理上的alpha值。
以下是设置图片来源的代码段:
BitmapSource b = MyClass.GetBitmapSource(filepath);
// just as a test, write out the bitmap to file to see if there's an alpha.
// see attached image1
BmpBitmapEncoder test = new BmpBitmapEncoder();
//test.Compression = TiffCompressOption.None;
FileStream stest = new FileStream(@"c:\temp\testbmp2.bmp", FileMode.Create);
test.Frames.Add(BitmapFrame.Create(b));
test.Save(stest);
stest.Close();
// effect is a class derived from ShaderEffect. The pixel shader associated with the
// effect displays the color channel of the texture loaded in the Image object
// depending on which member of the Point4D is set. In this case, we are showing
// the RGB channels but no alpha
effect.PixelMask = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f);
this.image1.Effect = effect;
this.image1.Source = b;
this.image1.UpdateLayout();
这是着色器代码(非常简单,但我认为我只是为了完整性而包含它):
sampler2D inputImage : register(s0);
float4 channelMasks : register(c0);
float4 main (float2 uv : TEXCOORD) : COLOR0
{
float4 outCol = tex2D(inputImage, uv);
if (!any(channelMasks.rgb - float3(1, 0, 0)))
{
outCol.rgb = float3(outCol.r, outCol.r, outCol.r);
}
else if (!any(channelMasks.rgb - float3(0, 1, 0)))
{
outCol.rgb = float3(outCol.g, outCol.g, outCol.g);
}
else if (!any(channelMasks.rgb - float3(0, 0, 1)))
{
outCol.rgb = float3(outCol.b, outCol.b, outCol.b);
}
else
{
outCol *= channelMasks;
}
if (channelMasks.a == 1.0)
{
outCol.r = outCol.a;
outCol.g = outCol.a;
outCol.b = outCol.a;
}
outCol.a = 1;
return outCol;
}
以下是上述代码的输出:
(抱歉,我没有足够的声望点来发布图片或显然超过2个链接)
在photoshop中保存到磁盘(C:\ temp \ testbmp2.bmp)的文件:
http://screencast.com/t/eeEr5kGgPukz
我的WPF应用程序中显示的图像(使用上面代码片段中的图像掩码):
http://screencast.com/t/zkK0U5I7P7