how to set up UWP C# StorageFile to store a SoftwareBitmap to a specific path

0

I'm trying to save a SoftwareBitmap to a file.

But I get error "The parameter is incorrect" when I do: StorageFile.GetFileFromPathAsync()

HERE IS THE ERROR...….

enter image description here

pathname = "diag ProcessFrame .JPG"

CODE FOR EVENT HANDLER FOR WEBCAM USB FRAME...……

        private void FrameReader_FrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
    {
        // Get frame image from camera:
        using (var frame = sender.TryAcquireLatestFrame())    //  ==>  MediaFrameReference 
        {
            // Got image?
            if (frame != null)
            {
                var renderer = _frameRenderers[frame.SourceKind];

                        renderer.ProcessFrame(frame);
            }
        }
    }






    // Process latest frame received from USB webcam.
    public void ProcessFrame( MediaFrameReference frame)
    {
        // Convert frame to a SoftwareBitmap of a valid format to display in an Image control:
            //      SoftwareBitmap Class
            //          https://docs.microsoft.com/en-us/uwp/api/windows.graphics.imaging.softwarebitmap?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(Windows.Graphics.Imaging.SoftwareBitmap)%3Bk(TargetFrameworkMoniker-.NETCore%2CVersion%3Dv5.0)%3Bk(DevLang-csharp)%26rd%3Dtrue
            var softwareBitmap = FrameRenderer.ConvertToDisplayableImage(frame?.VideoMediaFrame);



        if (softwareBitmap != null)
        {
            // Swap the processed frame to _backBuffer and trigger UI thread to render it
            softwareBitmap = Interlocked.Exchange(ref _backBuffer, softwareBitmap);          // does bytes = h X w ?

            // UI thread always reset _backBuffer before using it.  Unused bitmap should be disposed.
            softwareBitmap?.Dispose();

            ////////////////////////   DISPLAY FRAME LOCALLY   /////////////////////////

            // Changes to xaml ImageElement must happen in UI thread through Dispatcher
            var task = _imageElement.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                async () =>
                {
                    // Keep draining frames from the backbuffer until the backbuffer is empty.
                    SoftwareBitmap latest_frame_SoftwareBitmap;
                    while (( latest_frame_SoftwareBitmap = Interlocked.Exchange(ref _backBuffer, null)) != null)
                    {
                                                         // Diag to save frame to a file:
                                                                 //VideoMediaFrame inputFrame    =     frame.VideoMediaFrame;
                                                                 //SoftwareBitmap  frame_SoftwareBitmap = inputFrame.SoftwareBitmap;

                                                                 Common.SaveSoftwareBitmapToFile( latest_frame_SoftwareBitmap, "diag ProcessFrame .JPG");

                    . . .

        }





    // Saves encoded (ie. compressed) SoftwareBitmap image pixel data to a specific file pathname.
    public static async void SaveSoftwareBitmapToFile(SoftwareBitmap softwareBitmap, String pathname)
    {

        StorageFile outputFile = await StorageFile.GetFileFromPathAsync( pathname );
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ERROR OCCURS HERE



        using (IRandomAccessStream stream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            // Create an encoder with the desired format
            BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);

            // Set the software bitmap
            encoder.SetSoftwareBitmap(softwareBitmap);

            // Set additional encoding parameters, if needed
            //encoder.BitmapTransform.ScaledWidth = 320;
            //encoder.BitmapTransform.ScaledHeight = 240;
            //encoder.BitmapTransform.Rotation = Windows.Graphics.Imaging.BitmapRotation.Clockwise90Degrees;
            //encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
            encoder.IsThumbnailGenerated = true;

            try
            {
                await encoder.FlushAsync();
            }
            catch (Exception err)
            {
                const int WINCODEC_ERR_UNSUPPORTEDOPERATION = unchecked((int)0x88982F81);
                switch (err.HResult)
                {
                    case WINCODEC_ERR_UNSUPPORTEDOPERATION: 
                        // If the encoder does not support writing a thumbnail, then try again
                        // but disable thumbnail generation.
                        encoder.IsThumbnailGenerated = false;
                        break;
                    default:
                        throw;
                }
            }

            if (encoder.IsThumbnailGenerated == false)
            {
                await encoder.FlushAsync();
            }


        }
    }
c#
uwp
storagefile
asked on Stack Overflow Jan 3, 2019 by Doug Null

1 Answer

2

From the documentation of StorageFile:

ArgumentException

The path cannot be a relative path or a Uri. Check the value of path.

You need to specify an absolute path to the file.

Unrelated note: I would try some better naming conventions for your files. The extra space between the name and extension is kind of unconventional (and could cause problems for certain file systems like svn on a unix/linux based OS). From the context, a file name like "C:/path/to/diagProcessFrame.jpg" would honestly appear to look just fine.

answered on Stack Overflow Jan 3, 2019 by Chris • edited Jan 22, 2019 by Chris

User contributions licensed under CC BY-SA 3.0