C# 全息透镜2 UWP位图图像伪影

C# 全息透镜2 UWP位图图像伪影,c#,uwp,bitmap,uwp-xaml,hololens,C#,Uwp,Bitmap,Uwp Xaml,Hololens,我正在构建一个2D UWP应用程序,在HoloLens 2上运行。在应用程序中,我使用RenderTargetBitmap来渲染视频提要UI对象的位图,以从中获取作为软件位图对象的静止图像。令人沮丧的是,当在PC机上以x86模式运行它时,它工作正常。然而,当我在Hololens 2(ARM)上运行时,图像被一个伪影弄得乱七八糟。它似乎被分成了不匹配的行。我添加了将图像文件保存到设备上文件夹的功能,输出的图像看起来很好,但当它在应用程序UI中设置为imageSource时,它看起来很糟糕 在我的V

我正在构建一个2D UWP应用程序,在HoloLens 2上运行。在应用程序中,我使用RenderTargetBitmap来渲染视频提要UI对象的位图,以从中获取作为软件位图对象的静止图像。令人沮丧的是,当在PC机上以x86模式运行它时,它工作正常。然而,当我在Hololens 2(ARM)上运行时,图像被一个伪影弄得乱七八糟。它似乎被分成了不匹配的行。我添加了将图像文件保存到设备上文件夹的功能,输出的图像看起来很好,但当它在应用程序UI中设置为imageSource时,它看起来很糟糕

在我的VideoControl.xaml.cs代码隐藏中:

    private static async Task SetPauseImageSource()
    {
        await Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            SoftwareBitmap image = await Xaml2Bitmap.CreateBitmapFromElement(Instance, true);
            var source = new SoftwareBitmapSource();
            await source.SetBitmapAsync(image);
            Instance.imagePause.Source = source;
        });         
    }
在我的Xaml2Bitmap.cs类中:

    public static async Task<SoftwareBitmap> CreateBitmapFromElement(FrameworkElement uielement, bool saveFile = false, string filenamePrefix = "image")
    {           
        SoftwareBitmap bitmap = null;
        var renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(uielement);
        var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        bitmap = SoftwareBitmap.CreateCopyFromBuffer(pixelBuffer, BitmapPixelFormat.Bgra8, (int)uielement.ActualWidth, (int)uielement.ActualHeight, BitmapAlphaMode.Ignore);

        if (bitmap == null)
        {
            Debug.WriteLine("Bitmap is null");
        }

        if (saveFile)
        {
            var file = await SaveFile(filenamePrefix);

            using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
                encoder.SetPixelData(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Ignore,
                    (uint)renderTargetBitmap.PixelWidth,
                    (uint)renderTargetBitmap.PixelHeight,
                    logicalDpi,
                    logicalDpi,
                    pixelBuffer.ToArray());
                        
                await encoder.FlushAsync();
            }
        }
        return bitmap;
    }

    private static async Task<StorageFile> SaveFile(string filenamePrefix)
    {
        var savePicker = new FileSavePicker();
        savePicker.DefaultFileExtension = ".png";
        savePicker.FileTypeChoices.Add(".png", new List<string> { ".png" });
        savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        savePicker.SuggestedFileName = filenamePrefix + ".png";

        // Prompt the user to select a file
        var saveFile = await savePicker.PickSaveFileAsync();
        return saveFile;
    }     
public静态异步任务CreateBitmapFromElement(FrameworkElement uielement,bool saveFile=false,string filenamePrefix=“image”)
{           
软件位图位图=空;
var renderTargetBitmap=新建renderTargetBitmap();
等待renderTargetBitmap.RenderAsync(uielement);
var pixelBuffer=await renderTargetBitmap.GetPixelsAsync();
位图=软件位图.CreateCopyFromBuffer(pixelBuffer,BitmapPixelFormat.Bgra8,(int)uielement.ActualWidth,(int)uielement.ActualHeight,BitmapAlphaMode.Ignore);
如果(位图==null)
{
WriteLine(“位图为空”);
}
如果(保存文件)
{
var file=await SaveFile(filename前缀);
使用(var stream=await file.OpenAsync(FileAccessMode.ReadWrite))
{
var logicalDpi=DisplayInformation.GetForCurrentView().logicalDpi;
var编码器=等待BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId,流);
编码器.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode。忽略,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
等待编码器。FlushAsync();
}
}
返回位图;
}
专用静态异步任务保存文件(字符串filenamePrefix)
{
var savePicker=new FileSavePicker();
savePicker.DefaultFileExtension=“.png”;
savePicker.FileTypeChoices.Add(“.png”,新列表{.png});
savePicker.SuggestedStartLocation=PickerLocationId.PicturesLibrary;
savePicker.SuggestedFileName=filenamePrefix+“.png”;
//提示用户选择一个文件
var saveFile=await savePicker.PickSaveFileAsync();
返回保存文件;
}     


我们将一如既往地感谢您在这方面的任何帮助

这最终解决了它。我需要将位图文件保存到设备中并重新读取。虽然不理想,但效果很好

    public static async Task<string> CreateBitmapFromElement(FrameworkElement uielement)
    {
        SoftwareBitmap bitmap = null;
        var renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(uielement);
        var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
        bitmap = SoftwareBitmap.CreateCopyFromBuffer(pixelBuffer, BitmapPixelFormat.Bgra8, (int)uielement.ActualWidth, (int)uielement.ActualHeight, BitmapAlphaMode.Ignore);

        if (bitmap == null)
        {
            Debug.WriteLine("Bitmap is null");
        }

        var folder = KnownFolders.PicturesLibrary; 
        var file = await folder.CreateFileAsync("pause.bmp", CreationCollisionOption.ReplaceExisting);
       
        using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
            encoder.SetPixelData(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Ignore,
                (uint)renderTargetBitmap.PixelWidth,
                (uint)renderTargetBitmap.PixelHeight,
                logicalDpi,
                logicalDpi,
                pixelBuffer.ToArray());

            await encoder.FlushAsync();


            await stream.WriteAsync(pixelBuffer);

        }

        return file.Name;
    }

    private static async Task SetImageSource()
    {
        await Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
        {
            StorageFolder storageFolder = KnownFolders.PicturesLibrary;
            string imagePath = await Xaml2Bitmap.CreateBitmapFromElement(Instance);
            var file = await storageFolder.GetFileAsync(imagePath);

            using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
                BitmapImage bitmapImage = new BitmapImage();
                await bitmapImage.SetSourceAsync(fileStream);
                Instance.imagePause.Source = bitmapImage;
            }
        });         
    }
公共静态异步任务CreateBitmapFromElement(FrameworkElement uielement)
{
软件位图位图=空;
var renderTargetBitmap=新建renderTargetBitmap();
等待renderTargetBitmap.RenderAsync(uielement);
var pixelBuffer=await renderTargetBitmap.GetPixelsAsync();
位图=软件位图.CreateCopyFromBuffer(pixelBuffer,BitmapPixelFormat.Bgra8,(int)uielement.ActualWidth,(int)uielement.ActualHeight,BitmapAlphaMode.Ignore);
如果(位图==null)
{
WriteLine(“位图为空”);
}
var folder=KnownFolders.PicturesLibrary;
var file=wait folder.CreateFileAsync(“pause.bmp”,CreationCollisionOption.ReplaceExisting);
使用(var stream=await file.OpenAsync(FileAccessMode.ReadWrite))
{
var logicalDpi=DisplayInformation.GetForCurrentView().logicalDpi;
var编码器=等待BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId,流);
编码器.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode。忽略,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
等待编码器。FlushAsync();
wait stream.WriteAsync(像素缓冲区);
}
返回文件名;
}
私有静态异步任务SetImageSource()
{
wait Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,async()=>
{
StorageFolder StorageFolder=KnownFolders.PicturesLibrary;
字符串imagePath=wait Xaml2Bitmap.CreateBitmapFromElement(实例);
var file=await-storageFolder.GetFileAsync(imagePath);
使用(irandomaccesstream fileStream=await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapImage BitmapImage=新的BitmapImage();
等待bitmapImage.SetSourceAsync(文件流);
Instance.imagePause.Source=bitmapImage;
}
});         
}