c# - 如何从 UWP 中的 IBuffer 或字节数组创建 IDirect3DSurface

标签 c# uwp com media

我想从 UWP 中的一些 RenderTargetBitmap 创建视频。我通过使用 MediaClips 来做到这一点。 从 RenderTargetBitmap 我可以获得一个 IBuffer 或像素字节数组。 要创建一个 MediaClip,我需要一个图像文件或一个 IDirect3DSurface。 创建图像只是为了创建剪辑非常昂贵,所以我想到了使用 IDirect3DSurface。 我怎样才能做到这一点? 我试过这个:

        RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(RenderedGrid, 100, 100);

        IBuffer pixels = await renderTargetBitmap.GetPixelsAsync();
        var values = Enum.GetValues(typeof(DirectXPixelFormat));
        CanvasBitmap bitmap=null;

        foreach (DirectXPixelFormat format in values)
        {
            try
            {
                videoClip = new MediaComposition();
                bitmap = CanvasBitmap.CreateFromBytes(myWidget.Device, pixels, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, format);
                StorageFile video2 = await storageFolder.CreateFileAsync("video2" + ".mp4", CreationCollisionOption.ReplaceExisting);
                MediaClip d = MediaClip.CreateFromSurface(bitmap, DateTime.Now - previousFrame+new TimeSpan(100));
                videoClip.Clips.Add(d);
                await videoClip.RenderToFileAsync(video2);
                break;
            }
            catch(Exception e)
            {

            }
        }

我尝试了 DirectXPixelFormat 中的所有格式,但都不起作用。

我有一个名为 myWidgetCanvasControl 是空的。

我从 Ibuffer 创建了一个 CanvasBitmap(CanvasBitmap 实现了 IDirect3DSurface)

CanvasBitmap 创建一个 Mediaclip

将其添加到 MediaComposition

然后我尝试渲染到视频文件。当我尝试保存到文件时它抛出一个错误

System.Runtime.InteropServices.COMException Stream is not in a state to handle the request.

编辑: 我想出了问题出在哪里,但不知道为什么,也不知道如何解决。

            await videoClip.SaveAsync(video2);
            videoClip= await MediaComposition.LoadAsync(video2);
            var x=await videoClip.RenderToFileAsync(video2);

现在用这三行我可以保存视频,但是只使用第三行它会抛出上面的错误。我无法理解它。为什么保存和加载可以解决问题??

最佳答案

最可能的原因是,CanvasBitmap 有一个底层的 IDirce3DSurface 对象以及像 byte[] 或其他东西的图​​像数据,虽然我不确定这一点。

如果这是真的,那么从 byte[]IBuffer 创建一个 CanvasBitmap 将不会影响底层的 IDirect3DSurface,将只构建图像部分。您可以看到,通过将该图像保存在磁盘上,它没有给出任何错误。

但是如果您想跳过在磁盘上保存数据,我认为有一个解决方法:

如果你这样做,你可以构造底层 IDirect3DSurface Offscreen DrawingCanvasRenderTarget .

因此,您可以使用 CanvasBitmap 构建一个 CanvasRenderTarget,然后使用该 CanvasRenderTarget 构建一个 MediaClip:

CanvasRenderTarget rendertarget;
using (CanvasBitmap canvas = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), pixels, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, format))
{
     rendertarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), canvas.SizeInPixels.Width, canvas.SizeInPixels.Height, 96);
     using (CanvasDrawingSession ds = rendertarget.CreateDrawingSession())
     {
         ds.Clear(Colors.Black);
         ds.DrawImage(canvas);
     }
}
MediaClip d = MediaClip.CreateFromSurface(renderTarget, TimeSpan.FromMilliseconds(80));
mc.Clips.Add(m);

关于c# - 如何从 UWP 中的 IBuffer 或字节数组创建 IDirect3DSurface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51027900/

相关文章:

c# - COM 互操作是否尊重程序集加载的 .NET AppDomain 边界?

com - C# COM DLL : do I use Regasm, 或 Regsvr32?

组合框上的 C# 10 秒定时器选择索引

c# - ApplicationData.LocalSettings 中的日期时间

visual-studio - Windows 10 SDK 不会安装到 Visual Studio

windows - 如何以编程方式检测操作系统何时完成加载其所有应用程序\服务?

c# - 没有模型和 Entity Framework 的 ASP.NET MVC

c# - 转换十进制

c# - 检查二维数组的对角线 - 欧拉数 11

c# - 如何在 C# 中将类型为 "IBuffer"的值读取为字符串?