Uwp 屏幕截图视频颜色比屏幕上的颜色亮或暗

Uwp 屏幕截图视频颜色比屏幕上的颜色亮或暗,uwp,colors,win2d,Uwp,Colors,Win2d,我正试图从一系列UWP控件的截图中对视频进行编码。我可以使用导出静态图像,但当我尝试将一系列屏幕截图转换为视频时,生成的视频中的颜色为: 当我使用DirectXPixelFormat.B8G8R8A8UIntNormalized时,比屏幕上的更亮 使用DirectXPixelFormat.B8G8R8A8UIntNormalizedSrgb时比屏幕上的颜色暗 使用下面的代码 如何生成与屏幕上颜色相同的视频 额外问题:如何减少从ui元素到视频的步骤数 public async Task Ren

我正试图从一系列UWP控件的截图中对视频进行编码。我可以使用导出静态图像,但当我尝试将一系列屏幕截图转换为视频时,生成的视频中的颜色为:

  • 当我使用
    DirectXPixelFormat.B8G8R8A8UIntNormalized时,比屏幕上的更亮
  • 使用
    DirectXPixelFormat.B8G8R8A8UIntNormalizedSrgb时比屏幕上的颜色暗
使用下面的代码

如何生成与屏幕上颜色相同的视频

额外问题:如何减少从
ui元素到视频的步骤数

public async Task RenderVideo(UIElement content, StorageFile file)
        {
            TimeSpan frameTime = TimeSpan.FromMilliseconds(1000 / fps);

            MediaComposition composition = new();           

            var width = (uint)content.ActualSize.X;
            var height = (uint)content.ActualSize.Y;
            for (some loop)
            {
                // Code here to modify the "content" control

                RenderTargetBitmap rendertargetBitmap = new();
                await rendertargetBitmap.RenderAsync(content);

                CanvasRenderTarget rendertarget = null;
                using (CanvasBitmap canvas = CanvasBitmap.CreateFromBytes(
                    CanvasDevice.GetSharedDevice(),
                    await rendertargetBitmap.GetPixelsAsync(),
                    rendertargetBitmap.PixelWidth,
                    rendertargetBitmap.PixelHeight,

// Pixel format specified here:
                    DirectXPixelFormat.B8G8R8A8UIntNormalized))
                {
                    rendertarget = new CanvasRenderTarget(CanvasDevice.GetSharedDevice(), width, height, 96);
                    using CanvasDrawingSession ds = rendertarget.CreateDrawingSession();
                    ds.Clear(Colors.White);
                    ds.DrawImage(canvas, 0, 0);
                }

                MediaClip clip = MediaClip.CreateFromSurface(rendertarget, frameTime);
                composition.Clips.Add(clip);
            }

            var profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);

            // Avoid odd video dimensions which some encoders don't like
            profile.Video.Width = (width % 2 == 0) ? width : width + 1;
            profile.Video.Height = (height % 2 == 0) ? height : height + 1;

            var saveOperation = composition.RenderToFileAsync(file, MediaTrimmingPreference.Fast, profile);

            saveOperation.Progress = new AsyncOperationProgressHandler<TranscodeFailureReason, double>(async (info, progress) =>
            {
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
                {
                    // Report progress
                }));
            });
            saveOperation.Completed = new AsyncOperationWithProgressCompletedHandler<TranscodeFailureReason, double>(async (info, status) =>
            {
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
                {
                    // Report success of failure
                }));
            });
        }
公共异步任务RenderVideo(UIElement内容,存储文件) { TimeSpan frameTime=TimeSpan.From毫秒(1000/fps); MediaComposition=new(); var width=(uint)content.ActualSize.X; 变量高度=(uint)content.ActualSize.Y; 为了(一些循环) { //此处的代码用于修改“内容”控件 RenderTargetBitmap RenderTargetBitmap=new(); 等待rendertargetBitmap.RenderAsync(内容); CanvasRenderTarget rendertarget=null; 使用(CanvasBitmap canvas=CanvasBitmap.CreateFromBytes( CanvasDevice.GetSharedDevice(), 等待rendertargetBitmap.GetPixelsAsync(), rendertargetBitmap.PixelWidth, rendertargetBitmap.PixelHeight, //此处指定的像素格式: DirectXPixelFormat.B8G8R8A8UIntNormalized) { rendertarget=新的CanvasRenderTarget(CanvasDevice.GetSharedDevice(),宽度,高度,96); 使用CanvasDrawingSession ds=rendertarget.CreateDrawingSession(); ds.清晰(颜色:白色); ds.DrawImage(画布,0,0); } MediaClip clip=MediaClip.CreateFromSurface(渲染目标,帧时); 合成.剪辑.添加(剪辑); } var profile=MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p); //避免一些编码器不喜欢的奇怪视频尺寸 profile.Video.Width=(宽度%2==0)?宽度:宽度+1; profile.Video.Height=(高度%2==0)?高度:高度+1; var saveOperation=composition.RenderToFileAsync(文件,MediaTrimmingPreference.Fast,profile); saveOperation.Progress=新建AsyncOperationProgressHandler(异步(信息,进度)=> { 等待CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,新DispatchedHandler(()=> { //报告进展 })); }); saveOperation.Completed=新建AsyncOperationWithProgressCompletedHandler(异步(信息,状态)=> { 等待CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,新DispatchedHandler(()=> { //报告失败的成功 })); }); }
编辑1:

我想我已经找到了一个可能的问题,那就是如何使用
RenderTargetBitmap
渲染带有位图图像的Win2D画布。在我的主应用程序中,Win2D画布是半透明的,因此亮度可能来自白色背景,在屏幕上的处理方式可能与通过
RenderTargetBitmap
不同

以下是我所能简单描述的问题:

查看UWP应用程序。 此应用程序显示三个用于导出的按钮和三种不同方式渲染的颜色块:

  • 作为UWP矩形控件
  • 作为Win2D填充矩形
  • 作为Win2D位图
我在下文中提到这两幅图像:

A B

当Win2D画布(名为Colors的StackPanel)的父控件上未设置背景时,它在屏幕上显示为图像A,但会复制到剪贴板(使用按钮)上作为图像B(其中白色区域是透明的)

如果我将父控件的背景设置为黑色,它将在屏幕上显示为图像A,并作为图像A复制到剪贴板

如果我将父控件的背景设置为白色,它将在屏幕上显示为图像B,并作为图像B复制到剪贴板


我假设这是一个bug或者我遗漏了什么?

您可以尝试使用另一种方法从RenderTargetBitmap创建mediaclip,以查看是否也出现此问题,例如的回复。很遗憾,没有运气。我还尝试直接从
CanvasRenderTarget
创建媒体剪辑,没有任何更改,因此我想知道这是否与MediaEncodingProfile有关。我们正在就您的问题咨询其他工程师,可能会有一些延迟。好的,感谢您的跟进。基于上述信息,我们没有足够的资源来复制它。您能通过OneDrive或GitHub为我们提供一个服务吗?