2013-02-05 90 views
6

我可以從Assets中的圖片創建WriteableBitmap。如何從BitmapImage創建WriteableBitmap?

Uri imageUri1 = new Uri("ms-appx:///Assets/sample1.jpg"); 
WriteableBitmap writeableBmp = await new WriteableBitmap(1, 1).FromContent(imageUri1); 

但是,我無法從圖片目錄創建WriteableBitmap的,(我使用WinRT XAML Toolkit

//open image 
StorageFolder picturesFolder = KnownFolders.PicturesLibrary; 
StorageFile file = await picturesFolder.GetFileAsync("sample2.jpg"); 
var stream = await file.OpenReadAsync(); 

//create bitmap 
BitmapImage bitmap2 = new BitmapImage(); 
bitmap2.SetSource(); 
bitmap2.SetSource(stream); 

//create WriteableBitmap, but cannot 
WriteableBitmap writeableBmp3 = 
    await WriteableBitmapFromBitmapImageExtension.FromBitmapImage(bitmap2); 

這是正確的嗎?

回答

5

這是一個總的詭計,但它似乎工作...

// load a jpeg, be sure to have the Pictures Library capability in your manifest 
var folder = KnownFolders.PicturesLibrary; 
var file = await folder.GetFileAsync("test.jpg"); 
var data = await FileIO.ReadBufferAsync(file); 

// create a stream from the file 
var ms = new InMemoryRandomAccessStream(); 
var dw = new Windows.Storage.Streams.DataWriter(ms); 
dw.WriteBuffer(data); 
await dw.StoreAsync(); 
ms.Seek(0); 

// find out how big the image is, don't need this if you already know 
var bm = new BitmapImage(); 
await bm.SetSourceAsync(ms); 

// create a writable bitmap of the right size 
var wb = new WriteableBitmap(bm.PixelWidth, bm.PixelHeight); 
ms.Seek(0); 

// load the writable bitpamp from the stream 
await wb.SetSourceAsync(ms); 
3

WriteableBitmapFromBitmapImageExtension.FromBitmapImage()通過使用原來的Uri使用來加載BitmapImage和IIRC它只能與BitmapImage s從appx工作。在你的情況下竟然沒有一個開放的,因爲從圖片文件夾加載只能通過從流加載完成,所以從最快的選項,以最慢的(我覺得)是:

  1. 打開從圖像WriteableBitmap開始吧,這樣你就不需要重新打開它或者複製一些東西了。
  2. 如果您需要兩個副本 - 將其打開爲WriteableBitmap,然後創建一個新的大小相同的WriteableBitmap並複製像素緩衝區。
  3. 如果您需要有兩個副本 - 跟蹤用於打開第一個位圖的路徑,然後通過從與原始文件相同的文件加載它來創建新的WriteableBitmap

我認爲選項2可能比選項3更快,因爲您避免了兩次解碼壓縮圖像。

+0

謝謝你的回答,但是如何從get go打開圖像作爲writeablebitmap,?我認爲[這](http://stackoverflow.com/questions/4254225/opening-an-image-file-into-writablebitmap)可能會有所幫助,但我不能將位圖直接傳遞到一個可寫位圖。 – a2hiro

+0

沒有該鏈接適用於Silverlight。您需要爲圖像獲取StorageFile,例如使用文件選取器,然後等待OpenReadAsync,然後創建1x1 WriteableBitmap並等待SetSourceAsync。檢查此示例/擴展:http://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/4d568d4e4c6a#WinRTXamlToolkit/Imaging/WriteableBitmapLoadExtensions.cs –

4

這裏的方式讀取圖像的WriteableBitmap的工作原理菲利普指出:

StorageFile imageFile = ... 

WriteableBitmap writeableBitmap = null; 
using (IRandomAccessStream imageStream = await imageFile.OpenReadAsync()) 
{ 
    BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(
     imageStream); 

    BitmapTransform dummyTransform = new BitmapTransform(); 
    PixelDataProvider pixelDataProvider = 
     await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, 
     BitmapAlphaMode.Premultiplied, dummyTransform, 
     ExifOrientationMode.RespectExifOrientation, 
     ColorManagementMode.ColorManageToSRgb); 
    byte[] pixelData = pixelDataProvider.DetachPixelData(); 

    writeableBitmap = new WriteableBitmap(
     (int)bitmapDecoder.OrientedPixelWidth, 
     (int)bitmapDecoder.OrientedPixelHeight); 
    using (Stream pixelStream = writeableBitmap.PixelBuffer.AsStream()) 
    { 
     await pixelStream.WriteAsync(pixelData, 0, pixelData.Length); 
    } 
} 

注意,我我正在使用像素格式和alpha模式的可寫位圖使用和我通過。

相關問題