简体   繁体   中英

HoloLens 2 UWP bitmap image artifacting

I am building a 2D UWP app to run on HoloLens 2. In the app I am using RenderTargetBitmap to render a bitmap of video feed UI object to get a still from it as a SoftwareBitmap object. The frustrating part of this is that when running it in x86 mode on PC it works fine. However when I run on Hololens 2 (ARM) the image is garbled with an artifact that screws up the image. It appears to be split into mis-matching lines. I added the ability to save the image file out to a folder on the device and the outputted image looks fine but when it is set as an imageSource in the app UI it looks all screwed up.

In my VideoControl.xaml.cs codebehind:

    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;
        });         
    }

In my Xaml2Bitmap.cs class:

    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;
    }     

HoloLens 2 上的图像外观

Any help on this is much appreciated as always!

This ended up fixing it. I needed to save the bitmap file to the device and read it back in. Not ideal but it works.

    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;
            }
        });         
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM