2015-10-09 6 views
0

Я работаю над приложением для Windows phone 8.1 в Xamarin с mvvmCross. Мне нужно выбрать несколько изображений из телефонной библиотеки и отобразить их. Для этого я использую FileOpenPicker.SelectMultipleFilesAndContinue. Теперь мне нужно иметь возможность отображать все эти изображения в представлении. Одна из проблем заключается в том, что минимальное количество изображений должно быть 20, а изображения могут быть довольно большими. Сначала я попытался сделать их в байтовые массивы и использовал конвертер для их отображения.Выберите и покажите xamarin.form.Image в телефоне Windows

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 Images.

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. Используя coneverter, я устанавливаю значения.

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 но установка этих значений перед установкой источника фактически обрезает изображение сразу.

Этот метод отлично работает и полностью устраняет мою проблему нехватки