Я пытаюсь загрузить изображение в байтах с сервера, но изображение не отображается. Я получаю правильный массив байтов и меняю его размер. Он работает при добавлении изображения с камеры, но не работает при добавлении изображения из Интернета.
Я подтвердил, что изображение правильно сохранено и правильно загружено, поскольку я могу скопировать массив байтов и отобразить его, используя строку массива байтов.
Я обнаружил проблему при сравнении двух методов во время отладки, и в execturepickcommand он запускает мой метод "ItemSourceChanged", но не запускается с методом AddImages.
Коллекция
public class ImageGalleryPageModel
{
public ObservableCollection<ImageModel> Images
{
get { return images; }
}
private ObservableCollection<ImageModel> images = new ObservableCollection<ImageModel>();
}
Это работает с добавлением изображений из этого класса
private async Task ExecutePickCommand()
{
MediaFile file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
byte[] imageAsBytes;
using (MemoryStream memoryStream = new MemoryStream())
{
file.GetStream().CopyTo(memoryStream);
file.Dispose();
imageAsBytes = memoryStream.ToArray();
}
if (imageAsBytes.Length > 0)
{
IImageResizer resizer = DependencyService.Get<IImageResizer>();
imageAsBytes = resizer.ResizeImage(imageAsBytes, 1080, 1080);
ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
Images.Add(new ImageModel { Source = imageSource, OrgImage = imageAsBytes });
}
}
Затем я загружаю изображения и помещаю их в Коллекцию,
private void AddTheImages(int imageIssueId)
{
var imageData = App.Client.GetImage(imageIssueId);
byte[] imageAsBytes = imageData.Item1;
if (imageAsBytes.Length > 0)
{
IImageResizer resizer = DependencyService.Get<IImageResizer>();
imageAsBytes = resizer.ResizeImage(imageAsBytes, 1080, 1080);
ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
ImageGalleryViewModel.Images.Add(new ImageModel { Source = imageSource, OrgImage = imageAsBytes });
}
}
Xaml
<freshMvvm:FreshBaseContentPage NavigationPage.HasNavigationBar = "False"
xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:freshMvvm = "clr-namespace:FreshMvvm;assembly=FreshMvvm"
xmlns:converters = "clr-namespace:ASFT.Converters;assembly=ASFT"
xmlns:controls = "clr-namespace:ASFT.Controls;assembly=ASFT"
x:Class = "ASFT.Pages.IssuePage"
Padding = "4,25,4,4"
x:Name = "IssuePages">
...
<!--PictureGallery-->
<Label Text = "IMAGES"
HorizontalTextAlignment = "Start"
VerticalTextAlignment = "Center"
Style = "{StaticResource Labelfont}"
TextColor = "White" />
<Grid BindingContext = "{Binding ImageGalleryViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height = "128" />
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<controls:ImageGalleryControl Grid.Row = "0"
ItemsSource = "{Binding Images}">
<controls:ImageGalleryControl.ItemTemplate>
<DataTemplate>
<Image Source = "{Binding Source}"
Aspect = "AspectFit">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command = "{Binding Path=BindingContext.PreviewImageCommand, Source = {x:Reference IssuePages}}"
CommandParameter = "{Binding ImageId}" />
</Image.GestureRecognizers>
</Image>
</DataTemplate>
</controls:ImageGalleryControl.ItemTemplate>
</controls:ImageGalleryControl>
<Grid Grid.Row = "1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "*" />
<ColumnDefinition Width = "*" />
</Grid.ColumnDefinitions>
<Button Grid.Column = "0"
Text = "Add photo"
Command = "{Binding CameraCommand}" />
<Button Grid.Column = "1"
Text = "Pick photo"
Command = "{Binding PickCommand}" />
</Grid>
</Grid>
<Label Grid.Column = "0"
Grid.Row = "3"
Grid.ColumnSpan = "3"
Text = "{Binding ImageText}"
HorizontalTextAlignment = "Center"
VerticalTextAlignment = "Center"
TextColor = "White" />
...
</freshMvvm:FreshBaseContentPage>
И это Control, это itemsourcechanged, которые не запускаются.
private readonly StackLayout imageStack;
public ImageGalleryControl()
{
this.Orientation = ScrollOrientation.Horizontal;
imageStack = new StackLayout
{
Orientation = StackOrientation.Horizontal
};
this.Content = imageStack;
}
public new IList<View> Children
{
get { return imageStack.Children; }
}
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create<ImageGalleryControl, IList>
(
view => view.ItemsSource,
default(IList),
BindingMode.TwoWay,
propertyChanging: (bindableObject, oldValue, newValue) =>
{
((ImageGalleryControl)bindableObject).ItemsSourceChanging();
},
propertyChanged: (bindableObject, oldValue, newValue) =>
{
((ImageGalleryControl)bindableObject).ItemsSourceChanged(bindableObject, oldValue, newValue);
}
);
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
private void ItemsSourceChanging()
{
if (ItemsSource == null)
return;
}
private void CreateNewItem(IList newItem)
{
View view = (View)ItemTemplate.CreateContent();
if (view is BindableObject bindableObject)
bindableObject.BindingContext = newItem;
imageStack.Children.Add(view);
}
private void ItemsSourceChanged(BindableObject bindable, IList oldValue, IList newValue)
{
if (ItemsSource == null)
return;
if (newValue is INotifyCollectionChanged notifyCollection)
{
notifyCollection.CollectionChanged += (sender, args) =>
{
if (args.NewItems != null)
{
if (args.NewItems.Count > 0)
{
foreach (object newItem in args.NewItems)
{
View view = (View)ItemTemplate.CreateContent();
if (view is BindableObject bindableObject)
bindableObject.BindingContext = newItem;
imageStack.Children.Add(view);
}
}
}
else
{
imageStack.Children.Clear();
foreach (object item in ItemsSource)
{
View view = (View)ItemTemplate.CreateContent();
BindableObject bindableObject = (BindableObject) view;
if (bindableObject != null)
bindableObject.BindingContext = item;
imageStack.Children.Add(view);
}
}
if (args.OldItems != null)
{
// not supported
}
};
}
}
public DataTemplate ItemTemplate
{
get;
set;
}
public static readonly BindableProperty SelectedItemProperty =
BindableProperty.Create<ImageGalleryControl, object>
(
view => view.SelectedItem,
null,
BindingMode.TwoWay,
propertyChanged: (bindable, oldValue, newValue) =>
{
((ImageGalleryControl)bindable).UpdateSelectedIndex();
}
);
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
private void UpdateSelectedIndex()
{
if (SelectedItem == BindingContext)
return;
SelectedIndex = Children
.Select(c => c.BindingContext)
.ToList()
.IndexOf(SelectedItem);
}
public static readonly BindableProperty SelectedIndexProperty =
BindableProperty.Create<ImageGalleryControl, int>
(
carousel => carousel.SelectedIndex,
0,
BindingMode.TwoWay,
propertyChanged: (bindable, oldValue, newValue) =>
{
((ImageGalleryControl)bindable).UpdateSelectedItem();
}
);
public int SelectedIndex
{
get { return (int)GetValue(SelectedIndexProperty); }
set { SetValue(SelectedIndexProperty, value); }
}
private void UpdateSelectedItem()
{
SelectedItem = SelectedIndex > -1 ? Children[SelectedIndex].BindingContext : null;
}
}
Не работает без резайзера, с байтами все в порядке, я тестировал их на странице, которая принимает байтовый массив и преобразует его в изображение, отлично отображает изображение, но ничего не происходит, когда такой же массив попадает в коллекцию
вы пробовали веб-клиент для загрузки изображений? var webClient = новый WebClient (); byte [] imageBytes = webClient.DownloadData ("google.com/images/logos/ps_logo2.png "); Не уверен, поможет ли это здесь или нет.
Да, тоже пробовал. Не знаю, почему, почему один случай добавления изображений работает, а другой нет. Они почти такие же. Единственная разница в том, что я получаю другой файл из Интернета, а другой - с камеры телефона.
Вы на 100% уверены, что добавляете их в один и тот же экземпляр ImageGalleryPageModel?
На самом деле нет, но не знаю, как это проверить.
Не уверен, заметили ли вы, но в AddTheImages вы добавляете их в ImageGalleryViewModel, но у вас есть коллекция Observnable, определенная в ImageGalleryPageModel. Это всего лишь пример?
Для всех, кто смотрит это сегодня. Пожалуйста, не используйте этот код. Это ужасно.





public ObservableCollection<> Images {get;set;} = new ObservableCollection<>();с универсальной моделью ImageModel. Вам не нужно личное поле, это не имеет большого смысла.
Привет, чувак, спасибо за ответ. Но это пост почти трехлетней давности, ха-ха, и с тех пор я достаточно улучшился, чтобы писать намного лучший код, черт возьми, даже Xamarin настолько улучшился. В любом случае принял ваш ответ m8
это работает без изменения размера? Попробуйте сохранить загруженный образ на диск и открыть его - возможно, с вашими байтами что-то не так