Windows 8 - 将图像保存在XAML中作为本地文件(在Application文件夹中)

时间:2014-04-17 04:10:37

标签: c# xaml windows-8 windows-runtime windows-store-apps

在我的Windows商店应用程序中,我正在使用XAML中的 Image 控件显示图片。使用 WriteableBitmap 以代码方式设置Image控件的源代码。我正在尝试将此图像作为附件发送到电子邮件中。那有什么简单的方法吗?我试图在本地(在应用程序内)保存该图像并将该保存的图像附加到电子邮件。但是无法在本地保存。任何帮助表示赞赏。

这是代码。

bitmap = await WriteableBitmapRenderExtensions.Render(dataCanvas);
image.Source = bitmap;

dataCanvas是一个Canvas控件,由两个图像组成,一个位于另一个上方。实际上我必须在用户面部放置太阳镜顶部并将其显示为xaml中的另一个图像。同时发送该图片。

2 个答案:

答案 0 :(得分:3)

查看WinRT XAML工具包中的WriteableBitmapSaveExtensions课程,了解可用于保存SaveToFile()的所有WriteableBitmap扩展程序。

核心问题是:

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

    using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Premultiplied,
            (uint)writeableBitmap.PixelWidth,
            (uint)writeableBitmap.PixelHeight,
            96,
            96,
            pixels);
        await encoder.FlushAsync();

        using (var outputStream = writeStream.GetOutputStreamAt(0))
        {
            await outputStream.FlushAsync();
        }
    }
}

您可以使用方法的重载来获取编码器ID:

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

    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.GifEncoderId;
    }
    else if (new[] { ".jpg", ".jpeg", ".jpe", ".jfif", ".jif" }.Contains(ext))
    {
        encoderId = BitmapEncoder.JpegEncoderId;
    }
    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);

    return outputFile;
}

答案 1 :(得分:-1)

BitmapSource的任何子类(包括WritableBitmap)都可以传递给BitmapEncoderBitmapEncoder需要Stream来编写JPEG,PNG或其他图像。

然后,您可以使用邮件程序库来引用编码器使用的流,或使用共享合同,并直接传递流。

示例:

var bitmap = new WritableBitmap();

// ... draw your bitmap

var tempPath = // path to where you want to save (probably in your appx temp);
var encoder = new PngBitmapEncoder();

encoder.Frames.Add(bitmap);

using (var fs = new FileStream(tempPath))
{
    encoder.Save(fs);
}

// use the image saved to tempPath
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh871370.aspx