2015-02-23 165 views
0

我正在寫一個Windows Phone 8.1(WINRT)App。我有一個代碼@ Sergio0694它在Windows Phone 8.0/Silverlight上運行良好。它壓縮從圖庫中挑選的用戶照片,然後轉換爲base64字符串。Windows Phone 8.0到Windows Phone 8.1應用程序

它不適用於Windows Phone 8.1。誰能幫我 ?

public static async Task<String> ToCompressedBase64(this StorageFile imageFile, Page localPage) 
{ 
    //Get the stream from the StorageFile 
    IRandomAccessStream imageStream = await imageFile.OpenAsync(FileAccessMode.Read); 

    System.Diagnostics.Debug.WriteLine("Original size ---> " + imageStream.ToFileSize()); 

    //Compresses the image if it exceedes the maximum file size 
    imageStream.Seek(0); 
    BitmapDecoder compressDecoder = await BitmapDecoder.CreateAsync(imageStream); 
    PixelDataProvider compressionData = await compressDecoder.GetPixelDataAsync(); 
    byte[] compressionBytes = compressionData.DetachPixelData(); 

    //Set target compression quality 
    BitmapPropertySet propertySet = new BitmapPropertySet(); 
    BitmapTypedValue qualityValue = new BitmapTypedValue(0.5, PropertyType.Single); 
    propertySet.Add("ImageQuality", qualityValue); 

    imageStream.Seek(0); 
    imageStream = new InMemoryRandomAccessStream(); 
    BitmapEncoder compressionEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, imageStream, propertySet); 
    compressionEncoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, 
            compressDecoder.PixelWidth, compressDecoder.PixelHeight, 
            compressDecoder.DpiX, compressDecoder.DpiY, compressionBytes); 
    await compressionEncoder.FlushAsync(); 

    //Create a BitmapDecoder from the stream 
    BitmapDecoder resizeDecoder = await BitmapDecoder.CreateAsync(imageStream); 
#if DEBUG 
    System.Diagnostics.Debug.WriteLine("Old height and width ---> " + resizeDecoder.PixelHeight + " * " + resizeDecoder.PixelWidth + "\nCompressed size ---> " + imageStream.ToFileSize()); 
#endif 
    //Resize the image if needed 
    TaskCompletionSource<bool> completionSource = new TaskCompletionSource<bool>(); 
    localPage.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => 
    { 
     const int maxImageWidth = 48; 
     if (resizeDecoder.PixelWidth > maxImageWidth) 
     { 
      //Resize the image if it exceedes the maximum width 
      int newHeight = (int)(maxImageWidth * resizeDecoder.PixelHeight/resizeDecoder.PixelWidth); 
      WriteableBitmap tempBitmap = new WriteableBitmap((int)resizeDecoder.PixelWidth, (int)resizeDecoder.PixelHeight); 
      imageStream.Seek(0); 
      await tempBitmap.SetSourceAsync(imageStream); 
      WriteableBitmap resizedImage = tempBitmap.Resize(maxImageWidth, newHeight, WriteableBitmapExtensions.Interpolation.Bilinear); 

      //Assign to imageStream the resized WriteableBitmap 
      InMemoryRandomAccessStream resizedStream = new InMemoryRandomAccessStream(); 
      await resizedImage.ToStream(resizedStream, BitmapEncoder.JpegEncoderId); 
      imageStream = resizedStream; 
     } 
     completionSource.SetResult(true); 
    }).Forget(); 
    await completionSource.Task;   

    //Converts the final image into a Base64 String 
    imageStream.Seek(0); 

    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(imageStream); 
    PixelDataProvider pixels = await decoder.GetPixelDataAsync(); 
#if DEBUG 
    System.Diagnostics.Debug.WriteLine("New height and width ---> " + decoder.PixelHeight + " * " + decoder.PixelWidth + "\nSize after resize ---> " + imageStream.ToFileSize()); 
#endif 
    byte[] bytes = pixels.DetachPixelData(); 

    //Encode image 
    InMemoryRandomAccessStream encoded = new InMemoryRandomAccessStream(); 
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, encoded); 
    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, bytes); 
    await encoder.FlushAsync(); 
    encoded.Seek(0); 

    //Read bytes 
    byte[] outBytes = new byte[encoded.Size]; 
    await encoded.AsStream().ReadAsync(outBytes, 0, outBytes.Length); 

    //Create Base64 
    return Convert.ToBase64String(outBytes); 
} 
+0

通過「不工作」你是指它崩潰,或什麼都不做,或者你甚至不能建立/編譯應用程序? – 2015-02-23 10:07:05

+0

實際上上面的一些方法在windows phone 8.1中不起作用,如.Forget(); ..所以我試圖修改它,但它轉換大圖像時掛起 – 2015-02-23 10:16:25

回答

0

當使用TaskCompletionSource,等待就可以了,除了與TaskCompletionSource.SetResult你也應該處理可能發生的任何異常設置的結果,當你等待上TaskCompletionSource.Task通過調用TaskCompletionSource.SetException不會冒泡。

很有可能當你處理一個大文件時拋出一個異常,因此你的await completionSource.Task會掛起,因爲SetResult沒有被調用。

爲了說明這一點這裏的代碼的例子,做你想與調度員做W/O的邏輯是什麼,而且處理異常,上面解釋說:

public async Task<string> TestTaskCompletionSource(CoreDispatcher dispatcher) 
{ 
    TaskCompletionSource<bool> completionSource = new TaskCompletionSource<bool>(); 
    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => 
    { 
     try 
     { 
      Debug.WriteLine("Before delay"); 
      await Task.Delay(100); 
      Debug.WriteLine("After delay and before exception"); 
      throw new Exception("Test"); 
#pragma warning disable 162 
      completionSource.SetResult(true); 
#pragma warning restore 162 
     } 
     catch (Exception e) 
     { 
      completionSource.SetException(e); 
     } 
    }); 
    await completionSource.Task; 

    return "Test"; 
} 
相關問題