问题描述
我想从 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!