как настроить UWP C # StorageFile для хранения SoftwareBitmap по определенному пути - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь сохранить SoftwareBitmap в файл.

Но я получаю сообщение об ошибке "Параметр неверен", когда я это делаю: StorageFile.GetFileFromPathAsync ()

ЗДЕСЬ ОШИБКА...….

enter image description here

pathname = "diag ProcessFrame .JPG"

КОД ДЛЯ ОБРАБОТКИ СОБЫТИЙ ДЛЯ 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();
            }


        }
    }

1 Ответ

0 голосов
/ 04 января 2019

Из документации StorageFile:

ArgumentException

Путь не может быть относительным путем или Uri.Проверьте значение пути.

Вам необходимо указать абсолютный путь к файлу.

Примечание, не связанное с этим: Я бы попробовал некоторые более подходящие соглашения об именах для вашегофайлы.Дополнительный пробел между именем и расширением является своего рода нетрадиционным (и может вызвать проблемы для некоторых файловых систем, таких как svn в ОС на основе unix / linux).Исходя из контекста, имя файла, например "C:/path/to/diagProcessFrame.jpg", может показаться, что оно выглядит просто отлично.

...