如何将图像文件绘制/叠加到位图图像上?

3
我从 Kinect 传感器获得了一个视频源,它以位图的形式存储。我的问题是如何将一张图片(例如 .png)覆盖到视频源上。

视频源以位图源的方式显示在下面,我知道如何向位图绘制一条线,但如何将资源中的图片绘制到视频源上呢?

KinectVideo.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
                    PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel); 

以下是我试图通过将图像放置在视频源上实现的模拟效果: 我想要叠加到视频源的拳击袋图像。 绘制方法的更新实现,我认为这不是正确的实现方式,当将图像路径添加到.DrawImage时,我遇到了无效参数错误:
void myKinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
            {

                if (colorFrame == null) return;
                byte[] colorData = new byte[colorFrame.PixelDataLength];
                colorFrame.CopyPixelDataTo(colorData);

                 KinectVideo.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
                    PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel);

                Rect destRect2;

               //drawing image overlay to video feed
                 var drawingVisual = new DrawingVisual();
                 var drawingContext = drawingVisual.RenderOpen();
                 drawingContext.DrawImage(BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel),
                                           new Rect(new Size(colorFrame.Width, colorFrame.Height)));
                 drawingContext.DrawImage("Images/boxbag.jpg", destRect2);
                 drawingContext.Close();
                 var mergedImage = new RenderTargetBitmap(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Pbgra32);
                 mergedImage.Render(drawingVisual);

                 KinectVideo.Source = mergedImage; 


            }
        }
2个回答

5
要创建合并的图像,您可以使用DrawingContext,它提供了DrawTextDrawImage等方法,然后使用RenderTargetBitmap.Render进行渲染:
var drawingVisual = new DrawingVisual();
var drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawImage(BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel), 
                          new Rect(new Size(colorFrame.Width, colorFrame.Height)));
var overlayImage = new BitmapImage(new Uri("Images/boxbag.jpg"));
drawingContext.DrawImage(overlayImage, 
                          new Rect(x, y, overlayImage.Width, overlayImage.Height));
drawingContext.Close();
var mergedImage = new RenderTargetBitmap(colorFrame.Width, colorFrame.Height, 96, 96, PixelFormats.Pbgra32);
mergedImage.Render(drawingVisual);

KinectVideo.Source = mergedImage;

好的,所以我将这段代码放在我的视频源后面,并设置 drawingContext.DrawImage(KinectVideo, destRect1);drawingContext.DrawImage(PunchBag, destRect1); 这样就可以将图像绘制到视频中了,或者我理解错了吗? - Brian Var
要绘制位图源的区域。这意味着您可以在目标中绘制它,并且可能只从顶部/左侧绘制其中的一部分。将X/Y设置为所需位置,将Width/Height设置为与叠加图像尺寸匹配。 - aybe
从我的回答、@dkozl和其他回答者的观点来看,我认为你有很多解决问题的方法。如果你仍然无法得到正确的答案,那么请更新你的问题,但这次要用代码块,而不仅仅是一行代码。 - aybe
@Aybe @dkozl,我更新了我的问题以展示我如何尝试实现你们的解决方案。你们能告诉我哪里出错了吗?我在drawingContext.DrawImage(image2, destRect2);处得到了无效参数的错误提示。 - Brian Var
1
这正是我要写的,你不能直接将图像路径放进去,需要从中创建一个BitmapImage - aybe
显示剩余4条评论

1
如果您只是想在另一个UI控件的顶部显示一个Image,那么您可以在其他UI元素之后声明一个,或者设置Panel.ZIndex属性:
<Grid>
    <Border Background="Black" />
    <Image Source="/AppName;component/Images/ImageName.jpg" Width="50" Height="50" />
</Grid>

或者:

<Grid>
    <Image Source="/AppName;component/Images/ImageName.jpg" 
        Width="50" Height="50" Panel.ZIndex="1" />
    <Border Background="Black" />
</Grid>

请参考 StackOverflow 上的Bind Xaml bitmap image问题,了解如何将BitmapImage数据绑定到Image.ItemsSource属性。要将Image放置在特定位置,可以使用Image.Margin属性或将其放入Canvas中并使用Canvas.LeftCanvas.Top属性。请注意保留HTML标记。

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