How to create a IDirect3DSurface from an IBuffer or byte array in UWP(如何在 UWP 中从 IBuffer 或字节数组创建 IDirect3DSurface)
问题描述
我想从 UWP 中的几个 RenderTargetBitmap
创建一个视频.我通过使用 MediaClips
来做到这一点.从 RenderTargetBitmap
我可以得到一个 IBuffer
或像素的字节数组.要创建 MediaClip
,我需要一个图像文件或一个 IDirect3DSurface
.创建一个图像只是为了创建一个剪辑非常昂贵,所以我想到了使用 IDirect3DSurface
.我怎样才能做到这一点?我试过这个:
I want to create a video from a few RenderTargetBitmap
s in UWP. I am doing that by using MediaClips
.
From RenderTargetBitmap
i can get an IBuffer
or byte array of pixels.
To create a MediaClip
I need either an image file or an IDirect3DSurface
.
Creating an image just to create a clip is very expensive, so I thought of using IDirect3DSurface
.
How can I do this?
I have tried this:
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
中的所有格式,但都不行.
I try all the formats in DirectXPixelFormat
but none works.
我有一个名为 myWidget
的 CanvasControl
是空的.
I have a CanvasControl
named myWidget
that is empty.
我从 Ibuffer
创建一个 CanvasBitmap
(CanvasBitmap
实现 IDirect3DSurface
)
I create a CanvasBitmap
from Ibuffer
(CanvasBitmap
implements IDirect3DSurface
)
从 CanvasBitmap
将其添加到 MediaComposition
.
然后我尝试渲染到视频文件.当我尝试保存到文件时会引发错误
Then I try to render to video file.When i try to save to a file it throws an error
System.Runtime.InteropServices.COMException 流未处于状态处理请求.
System.Runtime.InteropServices.COMException Stream is not in a state to handle the request.
我知道问题出在哪里,但不知道为什么,也不知道如何解决.
I figured out where the problem is, but not why and not how to fix it.
await videoClip.SaveAsync(video2);
videoClip= await MediaComposition.LoadAsync(video2);
var x=await videoClip.RenderToFileAsync(video2);
现在有了这三行,我可以保存视频,但只使用第三行会引发上述错误.我无法理解它.为什么保存和加载可以解决问题??
Now with these three lines i can save the video, but using only the third line it throws the error above. I cannot make sense of it. Why does saving and loading fix the problem??
推荐答案
最可能的原因是,CanvasBitmap
有一个底层的 IDirce3DSurface
对象以及像 byte[]
或其他东西,虽然我不确定.
Most probable reason is that, CanvasBitmap
has an underlying IDirce3DSurface
object as well as image data like byte[]
or something else , though I am not sure about this.
如果是这样,那么从 byte[]
或 IBuffer
创建 CanvasBitmap
不会影响底层 IDirect3DSurface
,将只构建图像部分.您可以看到,通过将该图像保存在磁盘上,它不会出错.
If that's true, then creating a CanvasBitmap
from byte[]
or IBuffer
won't effect the underlying IDirect3DSurface
, the image part will be constructed only. You can see that by saving that image on the disk, it gives no error.
但是如果你想跳过在磁盘上保存数据,我认为有一个解决方法:
如果你这样做 Offscreen,你可以构建底层 IDirect3DSurface
绘制到 CanvasRenderTarget.
因此,您可以使用 CanvasBitmap
构造一个 CanvasRenderTarget
,然后使用该 CanvasRenderTarget
构造一个 MediaClip
:
So, you can use the CanvasBitmap
to construct a CanvasRenderTarget
and then use that CanvasRenderTarget
to contruct a 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);
这篇关于如何在 UWP 中从 IBuffer 或字节数组创建 IDirect3DSurface的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在 UWP 中从 IBuffer 或字节数组创建 IDirect3DSurface
基础教程推荐
- SSE 浮点算术是否可重现? 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- c# Math.Sqrt 实现 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01