Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用不带预乘alpha的图像类显示RGBA图像_Wpf_Image_Alpha_Bitmapsource - Fatal编程技术网

Wpf 使用不带预乘alpha的图像类显示RGBA图像

Wpf 使用不带预乘alpha的图像类显示RGBA图像,wpf,image,alpha,bitmapsource,Wpf,Image,Alpha,Bitmapsource,我试图根据用户输入显示纹理的单独R、G、B和A通道。我使用图像类来显示具有alpha通道的纹理。这些纹理加载到BitmapSource对象中,格式为Bgra32。问题是,当我将图像的源设置为BitmapSource时,如果我显示R、G或B通道的任意组合,我总是会得到预先乘以alpha值的像素。我编写了一个非常简单的着色器,对其进行了预编译,并使用ShaderEffect类指定给图像的Effect属性,以便分离和显示单独的通道,但显然,在WPF将alpha值预乘以纹理后,着色器将获得纹理 以下是用

我试图根据用户输入显示纹理的单独R、G、B和A通道。我使用图像类来显示具有alpha通道的纹理。这些纹理加载到BitmapSource对象中,格式为Bgra32。问题是,当我将图像的源设置为BitmapSource时,如果我显示R、G或B通道的任意组合,我总是会得到预先乘以alpha值的像素。我编写了一个非常简单的着色器,对其进行了预编译,并使用ShaderEffect类指定给图像的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();
以下是着色器代码(非常简单,但我想我应该包括它,只是为了完整性):

下面是上面代码的输出:
(对不起,我没有足够的声誉点数来发布图片或显然超过2个链接)

photoshop中保存到磁盘的文件(C:\temp\testbmp2.bmp):

在我的WPF应用程序中显示的图像(使用上面代码段中的图像掩码):

还有两张我无法放在原始帖子中的图像:使用图像掩码的WPF应用程序中的图像(0.0,0.0,0.0,1.0)-仅alpha:使用图像掩码的WPF应用程序中的图像(1.0,0.0,0.0,0.0)-仅红色通道:我无法查看您的工作图像(哑防火墙)。但是,为了让其他人能够帮助您,您可能需要发布
MyClass.GetBitmapSource()
@Abe的代码-我不能发布GetBitmapSource()…这是一堆代码,并且嵌入了一些专有的东西。同样,保存调用返回的BitmapSource肯定会在photoshop中生成一个带有R、G、B和a通道的.bmp文件。在任何情况下,我都找到了一个解决方案,但我不确定它是否是最优的。问题在于,出于性能原因,WPF总是将alpha预乘。因此,我所做的是使用一个WriteableBitmap将alpha通道从原始位图源中复制出来,并将其作为第二个tex2D传递给我的着色器。然后,我根据用户提供的通道掩码将它们组合在一起。
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;
}