IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Windows 10 UWP开发:如何保存图片文件

    汪宇杰发表于 2015-12-22 01:20:49
    love 0

    我的《上海轨道交通》UWP版中有个“保存运营线路图”的功能,可以把工程目录底下“Assets\shanghaimetro-xl.jpg”存到用户的设备上,并且让用户选择一个保存位置:

    这是个比较常见的功能,在UWP里实现也不复杂。最简单的是安装我的Edi.UWP.Helpers库:http://www.nuget.org/packages/Edi.UWP.Helpers/

    GayHub地址:https://github.com/EdiWang/UWP-Helpers/

    里面的BitmapExtensions有个拓展方法叫做

    public static Task<FileUpdateStatus> SaveToPngImage(this WriteableBitmap bitmap, PickerLocationId location, string fileName);

    因为接受的参数是WriteableBitmap,所以第一步是需要把工程底下的图片文件转换为WriteableBitmap格式:

    public static async Task<WriteableBitmap> LoadWriteableBitmap(string relativePath)
    {
        var storageFile = await Package.Current.InstalledLocation.GetFileAsync(relativePath.Replace('/', '\\'));
        var stream = await storageFile.OpenReadAsync();
        var wb = new WriteableBitmap(1, 1);
        wb.SetSource(stream);
        return wb;
    }
    

    然后就可以调用那个拓展方法保存了:

    var rmbp = await Helper.LoadWriteableBitmap("Assets/shanghaimetro-xl.jpg");
    await rmbp.SaveToPngImage(PickerLocationId.PicturesLibrary, "shmetro");

    具体的实现代码如下(也可以到我的gayhub上去看):

    public static async Task<FileUpdateStatus> SaveToPngImage(this WriteableBitmap bitmap, PickerLocationId location, string fileName) 
    { 
        var savePicker = new FileSavePicker 
        { 
            SuggestedStartLocation = location 
        }; 
        savePicker.FileTypeChoices.Add("Png Image", new[] { ".png" }); 
        savePicker.SuggestedFileName = fileName; 
        StorageFile sFile = await savePicker.PickSaveFileAsync(); 
        if (sFile != null) 
        { 
            CachedFileManager.DeferUpdates(sFile); 
    
    
            using (var fileStream = await sFile.OpenAsync(FileAccessMode.ReadWrite)) 
            { 
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream); 
                Stream pixelStream = bitmap.PixelBuffer.AsStream(); 
                byte[] pixels = new byte[pixelStream.Length]; 
                await pixelStream.ReadAsync(pixels, 0, pixels.Length); 
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, 
                          (uint)bitmap.PixelWidth, 
                          (uint)bitmap.PixelHeight, 
                          96.0, 
                          96.0, 
                          pixels); 
                await encoder.FlushAsync(); 
            } 
    
    
            FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(sFile); 
            return status; 
        } 
        return FileUpdateStatus.Failed; 
    } 

    有这么几点要说明:

    1. 因为我��,只写了png格式,大家可以自己扩充,注意BitmapEncoder.PngEncoderId这个也得改成对应格式的。

    2. 为了防止异步爆炸和另一个线程访问图片文件的情况,得用CachedFileManager.DeferUpdates和CachedFileManager.CompleteUpdatesAsync

    3. 因为是设计助手类库给别人爆,所以没有写try-catch,以便调用者自己管理异常情况,请注意异常处理。



沪ICP备19023445号-2号
友情链接