How to create a MediaClip from RenderTargetBitmap in an efficent way?

ⅰ亾dé卋堺 提交于 2019-12-10 12:48:35

问题


I am trying to capture a video of a XAML grid in UWP app using c#.

My approach.

1.Use RenderTargetBitmap to take a screenshot using renderTargetBitmap.RenderAsync

2.Convert the data to byte array.

3.Create an image file with the bytes and save it on disk using BitmapEncoder

4.Create a MediaClip from that image using MediaClip.CreateFromImageFileAsync

5.Add the clips to a MediaComposition composition.Clips.Add(clip)

6.Save as a video using composition.RenderToFileAsync(video);

Now this approach works.

But as you can imagine, going to disk to save the images and then read them to create the Clips, its SLOWWWW and the framerate is low.

I am looking for something that avoids going to the disk per each screenshot. Something that converts a RenderTargetBitmap (or IBuffer or byte[]) to MediaClips, without going to the disk, or some different approach to save the video.

I am developing UWP app for Hololens.


回答1:


Try something like this:

Same as you have done.

using (var soft = SoftwareBitmap.CreateCopyFromBuffer(pixels, BitmapPixelFormat.Bgra8, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, BitmapAlphaMode.Premultiplied))
{
   CanvasBitmap canvas = CanvasBitmap.CreateFromSoftwareBitmap(CanvasDevice.GetSharedDevice(), soft); 

   MediaClip m = MediaClip.CreateFromSurface(canvas, DateTime.Now - previousFrame); 
   composition.Clips.Add(m); 
}

Remember to catch the device lost exceptions and create a new device




回答2:


for those who are getting an exception while trying the answer from @Mediarea, try this:

CanvasRenderTarget rendertarget = null;
using (CanvasBitmap canvas = CanvasBitmap.CreateFromBytes(CanvasDevice.GetSharedDevice(), pixel_buffer, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight, Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized))
{
     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 m = MediaClip.CreateFromSurface(rendertarget, TimeSpan.FromMilliseconds(80));
mc.Clips.Add(m);

If you use this, the error Stream is not in a state to handle the request goes away.



来源:https://stackoverflow.com/questions/50951307/how-to-create-a-mediaclip-from-rendertargetbitmap-in-an-efficent-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!