1

我正在尝试根据用户输入显示纹理的单独 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

4

0 回答 0