使用WriteableBitmap时缓冲区大小不足?

3
我正在修改ColorBasic Kinect示例,以便在视频流上叠加显示图像。我所做的是加载一个带有透明背景的图像(现在是GIF格式,但可能会更改),并写入显示的位图。
我的错误是正在写入的缓冲区太小了。我看不到实际的错误(我是XAML/C#/Kinect的新手),但WriteableBitmap的大小是1920x1080,我想要复制的位图是200x200,为什么会出现这个错误?我看不到透明背景可能会造成任何伤害,但我开始怀疑...
请注意,如果没有最后的WritePixels,代码可以正常工作,并且我可以看到网络摄像头的输出。以下是我的代码。
叠加图像:
public BitmapImage overlay = new BitmapImage(new Uri("C:\\users\\user\\desktop\\something.gif"));

回调函数用于显示Kinect网络摄像头的图像(参见默认示例ColorBasic),这里有些微小的修改:
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
    // ColorFrame is IDisposable
    using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
    {
        if (colorFrame != null)
        {
            FrameDescription colorFrameDescription = colorFrame.FrameDescription;

            using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
            {
                this.colorBitmap.Lock();

                // verify data and write the new color frame data to the display bitmap
                if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
                {
                    colorFrame.CopyConvertedFrameDataToIntPtr(
                        this.colorBitmap.BackBuffer,
                        (uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
                        ColorImageFormat.Bgra);

                    this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                }

                if(this.overlay != null)
                {
                    // Calculate stride of source
                    int stride = overlay.PixelWidth * (overlay.Format.BitsPerPixel / 8);

                    // Create data array to hold source pixel data
                    byte[] data = new byte[stride * overlay.PixelHeight];

                    // Copy source image pixels to the data array
                    overlay.CopyPixels(data, stride, 0);

                    this.colorBitmap.WritePixels(new Int32Rect(0, 0, overlay.PixelWidth, overlay.PixelHeight), data, stride, 0);
                }

                this.colorBitmap.Unlock();
            }
        }
    }
}
1个回答

2

您的overlay.Format.BitsPerPixel / 8将会是1(因为它是一个gif),但您正在尝试将其复制到不是gif的东西上,可能是BGRA(32位)。 因此,您在大小上有了巨大的差异(4倍)。


.WritePixels应该接受目标缓冲区的步幅值,但您将步幅值传递给了覆盖层(这也可能导致奇怪的问题)。


最后,即使一切顺利,您的覆盖层实际上也不会“覆盖”任何内容,而是替换--因为我在您的代码中没有看到任何Alpha混合数学。

将您的.gif切换为.png(32位),看看是否有帮助。

此外,如果您正在寻找AlphaBltMerge类型的代码:我在此处编写了整个代码...非常容易理解。


使用Alpha通道合并2个32位图像


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接