2015-02-23 9 views
0

Я пишу Приложение Windows Phone 8.1 (WINRT). У меня есть код, указанный @ Sergio0694, который работает на Windows Phone 8.0/Silverlight. Он сжимает фотографию пользователя, выбранную из галереи, а затем преобразует в строку base64.Windows Phone 8.0 To 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

К «не работает» вас означает, что он сбой или ничего не делает, или вы даже не можете создавать/компилировать приложение? –

+0

фактически некоторые из вышеперечисленных методов не работают в Windows Phone 8.1, например .Forget(); .. поэтому я попытался изменить его, но он зависает при преобразовании больших изображений –

ответ

0

При использовании TaskCompletionSource и ожидает от него, в дополнение к установке результата с TaskCompletionSource.SetResult вы также должны обрабатывать любое исключение, которое может произойти, что не будет ыми, когда вас ждут на TaskCompletionSource.Task по телефону TaskCompletionSource.SetException.

Очень вероятно, что когда вы имели дело с большим файлом, было исключено исключение, и тогда ваш await completionSource.Task будет висеть из-за того, что не был вызван SetResult.

Чтобы проиллюстрировать это, вот пример кода, который делает то, что вы пытаетесь сделать с диспетчером без вашей логики, а также обрабатывает исключение, как описано выше:

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"; 
} 
Смежные вопросы