Сохранить изображение с помощью FileSavePicker

У меня есть изображение, отображаемое в элементе управления изображением, и мне нужно сохранить это изображение с помощью FileSavePicker.

Вот что я сделал:

 Dim fileSavePicker As New FileSavePicker()
        fileSavePicker.FileTypeChoices.Add("PNG", New String() {".png"})
        fileSavePicker.FileTypeChoices.Add("JPG", New String() {".jpg"})
        fileSavePicker.FileTypeChoices.Add("BMP", New String() {".bmp"})
        fileSavePicker.FileTypeChoices.Add("TIFF", New String() {".tiff"})
        fileSavePicker.FileTypeChoices.Add("EXIF", New String() {".exif"})
        fileSavePicker.FileTypeChoices.Add("ICO", New String() {".ico"})
        Dim saveFile As StorageFile = Await fileSavePicker.PickSaveFileAsync()
        If saveFile IsNot Nothing Then
          //Here I need to save that Image
        End If

Он сохраняет изображение, но с «0 КБ» и показывает мне пустое изображение.

Что я должен делать?

Редактировать:

Это ошибка, которую я получаю:

SaveToFile не является членом Windows.UI.XAML.Media.Imaging.WriteableBitmap'.

И аналогично для «Загрузить»

Редактировать:

Вот как я пытаюсь загрузить изображение:

Private Async Sub Scenario1Button_Click(sender As Object, e As RoutedEventArgs) Handles Scenario1Button.Click
    Image1.Visibility = Windows.UI.Xaml.Visibility.Visible
    LayoutRoot.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    grdImages.Visibility = Windows.UI.Xaml.Visibility.Collapsed
    Dim openPicker As New FileOpenPicker
    openPicker.ViewMode = PickerViewMode.List
    openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary
    openPicker.FileTypeFilter.Add("*")
    Dim files As IReadOnlyList(Of StorageFile) = Await openPicker.PickMultipleFilesAsync
    If files.Count > 0 Then
        'Application now has read/write access to the picked file(s)
        For Each file In files
            Dim stream = Await file.OpenAsync(Windows.Storage.FileAccessMode.Read)
            Dim image As New BitmapImage()
            image.SetSource(stream)
            Image1.Source = image
            LayoutRoot.Visibility = Windows.UI.Xaml.Visibility.Collapsed
        Next file
    Else
    End If
End Sub

введите здесь описание изображения


person coder    schedule 18.03.2012    source источник
comment
Как вы связали FileSavePicker с элементом управления Image? Другими словами, как вы сообщили FileSavePicker, что вы сохраняете?   -  person Bill Sempf    schedule 19.03.2012
comment
@Bill-Это то, что я хотел бы знать. Я не могу знать, как ведет себя FileSavePicker, но для приведенного выше кода он просто сохраняет фиктивное изображение.   -  person coder    schedule 19.03.2012


Ответы (1)


Согласно документации:

Когда вызов этого метода завершается успешно, он возвращает объект storageFile, созданный для представления сохраненного файла. Имя файла, расширение и местоположение этого storageFile совпадают с указанными пользователем, но файл не имеет содержимого. Чтобы сохранить содержимое файла, ваше приложение должно записать содержимое в этот файл storageFile.

Итак, вы получаете файл хранилища, и вам нужно записать в него.

Сохранение BitmapImage невозможно, поэтому вам нужно начать с загрузки изображения в WriteableBitmap. Если вы просто копируете исходный файл, вы можете просто загрузить его в поток и сохранить обратно в новый файл хранилища. Если вы хотите пойти по маршруту WriteableBitmap — вот набор методов расширения, которые вы могли бы использовать для загрузки/сохранения изображения, если бы использовали C#:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;

namespace Xyzzer.WinRT.Extensions
{
    public static class WriteableBitmapSaveExtensions
    {
        public static async Task<WriteableBitmap> Load(string relativePath)
        {
            return await new WriteableBitmap(1, 1).Load(relativePath);
        }

        public static async Task<WriteableBitmap> Load(this WriteableBitmap writeableBitmap, string relativePath)
        {
            var storageFile = await Package.Current.InstalledLocation.GetFileAsync(relativePath.Replace('/', '\\'));
            return await writeableBitmap.Load(storageFile);
        }

        public static async Task<WriteableBitmap> Load(this WriteableBitmap writeableBitmap, StorageFile storageFile)
        {
            var stream = await storageFile.OpenReadAsync();
            var wb = new WriteableBitmap(1, 1);
            wb.SetSource(stream);
            return wb;
        }

        public static async Task SaveToFile(this WriteableBitmap writeableBitmap)
        {
            await writeableBitmap.SaveToFile(
                KnownFolders.PicturesLibrary,
                string.Format(
                    "{0}_{1}.png",
                    DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
                    Guid.NewGuid()));
        }

        public static async Task SaveToFile(this WriteableBitmap writeableBitmap, StorageFolder storageFolder)
        {
            await writeableBitmap.SaveToFile(
                storageFolder,
                string.Format(
                    "{0}_{1}.png",
                    DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
                    Guid.NewGuid()));
        }

        public static async Task SaveToFile(this WriteableBitmap writeableBitmap, StorageFolder storageFolder, string fileName)
        {
            StorageFile outputFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

            Guid encoderId;

            var ext = Path.GetExtension(fileName);

            if (new[] { ".bmp", ".dib" }.Contains(ext))
            {
                encoderId = BitmapEncoder.BmpEncoderId;
            }
            else if (new[] { ".tiff", ".tif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".gif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".jpg", ".jpeg", ".jpe", ".jfif", ".jif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".hdp", ".jxr", ".wdp" }.Contains(ext))
            {
                encoderId = BitmapEncoder.JpegXREncoderId;
            }
            else //if (new [] {".png"}.Contains(ext))
            {
                encoderId = BitmapEncoder.PngEncoderId;
            }

            await writeableBitmap.SaveToFile(outputFile, encoderId);
        }

        public static async Task SaveToFile(this WriteableBitmap writeableBitmap, StorageFile outputFile, Guid encoderId)
        {
            try
            {
                Stream stream = writeableBitmap.PixelBuffer.AsStream();
                byte[] pixels = new byte[(uint)stream.Length];
                await stream.ReadAsync(pixels, 0, pixels.Length);

                int offset;

                for (int row = 0; row < (uint)writeableBitmap.PixelHeight; row++)
                {
                    for (int col = 0; col < (uint)writeableBitmap.PixelWidth; col++)
                    {
                        offset = (row * (int)writeableBitmap.PixelWidth * 4) + (col * 4);
                        byte B = pixels[offset];
                        byte G = pixels[offset + 1];
                        byte R = pixels[offset + 2];
                        byte A = pixels[offset + 3];

                        // convert to RGBA format for BitmapEncoder
                        pixels[offset] = R; // Red
                        pixels[offset + 1] = G; // Green
                        pixels[offset + 2] = B; // Blue
                        pixels[offset + 3] = A; // Alpha
                    }
                }

                IRandomAccessStream writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite);
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
                encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied, (uint)writeableBitmap.PixelWidth, (uint)writeableBitmap.PixelHeight, 96, 96, pixels);
                await encoder.FlushAsync();
                await writeStream.GetOutputStreamAt(0).FlushAsync();
            }
            catch (Exception ex)
            {
                string s = ex.ToString();
            }
        }
    }
}
person Filip Skakun    schedule 19.03.2012
comment
@Filip-Спасибо за ваше подробное объяснение и если я конвертирую его в VB.Net и получаю вышеупомянутые ошибки. - person coder; 19.03.2012
comment
Я думаю, что ваша трансформация не удалась. Я не слишком много разрабатываю VB, но быстрый поиск по методам расширения в VB говорит, что вам нужно префикс методов расширения с атрибутом ‹Extension()›. Большинство методов в моем коде были методами расширения (все с этим WriteableBitmap в качестве первого параметра. - person Filip Skakun; 19.03.2012
comment
@Filip-Нет проблем. Я посмотрю на это. - person coder; 19.03.2012
comment
Или вы можете создать библиотеку классов C# с кодом C#, а затем ссылаться, импортировать и использовать ее из своего проекта VB. - person Filip Skakun; 19.03.2012
comment
@Fiilip-Это помогло, и как мне это назвать при нажатии кнопки. - person coder; 19.03.2012
comment
Что ж, у вас есть свой saveFile из fileSavePicker.PickSaveFileAsync(). Если у вас есть WriteableBitmap с именем myBitmap, который вы хотите сохранить, просто выполните myBitmap.Save(saveFile) - person Filip Skakun; 19.03.2012
comment
@Filip-Извините за беспокойство. Поскольку я новичок в этом записываемом растровом изображении и XAML, мне нужно некоторое время, чтобы привыкнуть к этому. Я добавил код для загрузки изображения из того, как я могу получить записываемое растровое изображение. - person coder; 19.03.2012