luberda-molinet / FFImageLoading

Image loading, caching & transforming library for Xamarin and Windows
MIT License
1.42k stars 377 forks source link

Image not reloading #282

Closed Spierki closed 8 years ago

Spierki commented 8 years ago

Hello, I'm trying to use the library but I'm stuck because the image isn't reloading.

I used the mvvm pattern with the xlabs helpers.

This is my xaml file:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
             xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
             x:Class="Cartea.View.CropView">
  <ContentPage.Content>
        <ffimageloading:CachedImage HorizontalOptions="Center" VerticalOptions="Center"
            WidthRequest="300" HeightRequest="300"
            DownsampleToViewSize="true"
            Source = "{Binding ImagePath, Mode=TwoWay}">
            <ffimageloading:CachedImage.Transformations>
                <fftransformations:CropTransformation  />
            </ffimageloading:CachedImage.Transformations>
        <ffimageloading:CachedImage.GestureRecognizers>
          <PinchGestureRecognizer PinchUpdated="OnPinchUpdated"/>
          <PanGestureRecognizer PanUpdated="OnPanUpdated"/>
        </ffimageloading:CachedImage.GestureRecognizers>
        </ffimageloading:CachedImage>
  </ContentPage.Content>
</ContentPage>

This is my view code:

public partial class CropView : ContentPage
{
    CropViewModel test;
    public CropView()
        {
            Title = "CropTransformation Demo";
            InitializeComponent();
            test = new CropViewModel();
            BindingContext = test;
        }

        void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
        {
            test.PinchImage(e);
        }

        void OnPanUpdated(object sender, PanUpdatedEventArgs e)
        {
            test.PanImage(e);
        }
    }

In my viewmodel this is how I initialize my variables:

  public void Init(string pathSource, Stream streamSource)
        {
            ImagePath = pathSource;
            ImageSource = Xamarin.Forms.ImageSource.FromStream(() =>
            { return streamSource; });
            _originalStream = streamSource;

        }

Then the reload method:

 void ReloadImage()
        {
            var currentImage = Xamarin.Forms.ImageSource.FromStream(() => { return _originalStream; }); 
            CachedImage.InvalidateCache(ImageSource, FFImageLoading.Cache.CacheType.All, true);

            Transformations = new List<ITransformation>() {
                new CropTransformation(CurrentZoomFactor, CurrentXOffset, CurrentYOffset, 1f, 1f)
            };

            ImageSource = null;
            ImageSource = currentImage;
        }

        public void Reload()
        {
            Transformations = null;
            CurrentZoomFactor = 1d;
            CurrentXOffset = 0d;
            CurrentYOffset = 0d;
            ImageSource = Xamarin.Forms.ImageSource.FromStream(() =>
            { return _originalStream; });
        }
daniel-luberda commented 8 years ago

var currentImage = Xamarin.Forms.ImageSource.FromStream(() => { return _originalStream; });

You can't do that. _originalStream is disposed after first image loading operation (the same behavior is for standard Xamarin.Forms Image. You must return a new stream instance every time (eg. create it from a byte array).

BTW: Did you try CachedImage.ReloadImage() method?

Spierki commented 8 years ago

@daniel-luberda In my Init method I already have the path of the picture too so I tried with the method:

var currentImage = Xamarin.Forms.ImageSource.FromFile(imagePath); 

It's not working, same reason than with _originalStream?

I tried to use CachedImage.ReloadImage() but I can't call this function, have you a sample ?

lengluo commented 8 years ago

@Spierki The same problem, and I also use the XLabs.forms. So is there any solutions you have?

daniel-luberda commented 8 years ago

I don't understand. Could you elaborate?

Simple explanation is that var currentImage = Xamarin.Forms.ImageSource.FromFile(imagePath); is giving you only a pointer to the file. You have to load it to the image view after that. Eg. cacheImage.Source = currentImage;