2015-10-09 44 views
0

我正在使用mvvmCross在Xamarin中爲Windows Phone 8.1的應用程序工作。我需要從手機庫中選擇多個圖像並顯示它們。我正在使用FileOpenPicker.SelectMultipleFilesAndContinue來這樣做。現在我需要能夠在視圖中顯示所有這些圖像。一個問題是圖像的最小數量必須是20,並且圖像可能非常大。 首先,我試着把它們變成字節數組,並用轉換器來顯示它們。在windows phone中選擇並顯示xamarin.form.Image

public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) { 

     if (args.Files.Count > 0) { 

      foreach (StorageFile file in args.Files) { 

       IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 

       byte[] bytes = null; 
       using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) { 
        bytes = new byte[fileStream.Size]; 
        await reader.LoadAsync((uint)fileStream.Size); 
        reader.ReadBytes(bytes); 
       } 

       callback(bytes); 
      }    
     } 
     else { 

     } 
    } 

這種方法似乎在第一次嘗試工作,但只要我有5張試了一下它停止工作。當回調完成後,該應用剛剛退出。沒有錯誤信息或任何東西。 (我的猜測是內存過載。)

之後,我發現了一個小解決方案,我把字節數組,並使他們Xamarin.Form圖像。

public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) { 
     if (args.Files.Count > 0) { 
      foreach (StorageFile file in args.Files) { 
       IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); 

       byte[] bytes = null; 
       using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) { 
        bytes = new byte[fileStream.Size]; 
        await reader.LoadAsync((uint)fileStream.Size); 
        reader.ReadBytes(bytes); 
       } 
       Image image = new Image(); 
       image.Source = ImageSource.FromStream(() => new MemoryStream(bytes)); 
       var iets = image.Source.BindingContext; 

       callback(image); 
      }    
     } 
     else { 

     } 

這似乎是照顧內存過載的問題。現在唯一的另一個問題是,我似乎無法找到任何方式顯示這些圖像。

<GridView ItemsSource="{Binding SelectedImages}"> 
        <GridView.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <Image Style="{StaticResource imageListImage}" Source="{Binding Source}"/> 
           <Button Style="{StaticResource imageListXButton}"> 
            <Button.Background> 
             <ImageBrush ImageSource="ms-appx:///Resources/XButton.png"/> 
            </Button.Background> 
           </Button> 
          </Grid> 
         </DataTemplate> 
        </GridView.ItemTemplate> 

我嘗試用簡單的綁定顯示它們。我還沒有找到任何可行的方式。有誰知道一種方法來顯示這些圖像,如果不是什麼將是最好的選擇使用字節而不使用太多的內存。

回答

0

經過一番深入的挖掘,我找到了答案。這比我想象的要快得多。我開始使用BitmapImage中的decodepixel。使用錐形器我設置了這些值。

public object Convert(object value, Type targetType, object parameter, string language) { 

     BitmapImage image = (BitmapImage)value; 

     image.DecodePixelType = DecodePixelType.Logical; 

     if (image.PixelHeight >= image.PixelWidth) { 
      image.DecodePixelHeight = 100; 
     } 
     else { 
      image.DecodePixelWidth = 100; 
     } 
     return image; 
    } 

奇怪的是,它確實有些時間工作。但由於某種原因,它不適用於所有圖像,有時甚至將它們丟棄。 但經過很多測試後,我終於找到了我要找的東西。

    BitmapImage bitmap = new BitmapImage(); 
        BitmapImage temp = new BitmapImage(); 

        bitmap.DecodePixelType = DecodePixelType.Logical; 

        using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) { 
         IRandomAccessStream secondStream = fileStream.CloneStream(); 
         BitmapImage temp = new BitmapImage(); 
         temp.SetSource(fileStream); 
         if (temp.PixelHeight >= temp.PixelWidth) { 
          bitmap.DecodePixelHeight = 150; 
         } 
         else { 
          bitmap.DecodePixelWidth = 150; 
         } 
         bitmap.SetSource(secondStream); 
        } 

出於某種原因,設置源後設置decodepixel使得inconsitent但設置源之前設置這些值實際上裁剪圖像的時候了。

此方法完美並完全解決了我的內存不足問題