beraybentesen / glide-xamarin-android

Glide Xamarin Binding
https://www.nuget.org/packages/Glide.Xamarin/
61 stars 14 forks source link

Loading images with different dimensions not working #4

Closed bgillman22 closed 7 years ago

bgillman22 commented 7 years ago

I have been struggling with this for a while...I am trying to resize local resources to be used in an animation drawable. This process is a foreach within a Task with a Continue at the end that is used to start the animation. The first time the images are loaded and resized with no issue. When the screen orientation changes, the Glide portion silently fails within the foreach and never hits the Continue. So, in this orientation, I just see the initial image from the xml. When I switch the orientation back to the original position, the animation starts with the resized images as expected.

It was my understanding that, when the dimensions of the image change, the image will be processed again. I have tried many caching configurations, using signatures and nothing is working. Any ideas?

    public void LoadSplashAnimationAsync(ImageView imageView, Action<AnimationDrawable> action)
    {
        try
        {
            Task.Run(async () =>
            {
                var frames = GetAnimation();
                SetDimensions(imageView.Height);
                foreach (var frame in frames)
                {
                    var image = await ResizeImageAsyncFromResources(frame);
                    Drawable.AddFrame(image, frame.Milliseconds);
                }
            }).ContinueWith(tsk =>  //**this is called on load, after orientation change, continue is never hit**
            { 
                if (tsk.Exception != null)
                    imageView.SetImageResource(Resource.Drawable.babybored46);
                else
                    action(Drawable);
            });
        }
        catch (Exception error)
        {
            imageView.SetImageResource(Resource.Drawable.babybored46);
        }
    }

    private async Task<Drawable> ResizeImageAsyncFromResources(AnimationModel frame)
    {
        var target = await Glide
                .With(Activity)
                .FromResource()
                .Load(frame.Id)
                .Error(Resource.Drawable.babybored46)
                .Into(Width, Height)
                .GetAsync();
        var drawable = (Com.Bumptech.Glide.Load.Resource.Drawable.GlideDrawable)target;
        return drawable.Mutate();
    }
beraybentesen commented 7 years ago

Glide resizes automatically to save memory. That is the issue. Can you add .Override method like (400,400) to see what happens ?

bgillman22 commented 7 years ago

Wow. It worked! But I don't understand why? When I tried using the calculated values with the override, it failed to hit the Continue. So, the first time around the Override width was 581, height was 710, which worked. The second pass the width was 478 and the height was 584 and it failed to hit the Continue.

Can you explain why using 400 works and other values fail? Thanks so much for the quick help!

beraybentesen commented 7 years ago

There is two problems. First is related to binding. I had to remove download completed class which was abstract and Xamarin binding does not like that therefore you are not able to listen and return drawable in that. Second is your ResizeTask. Glide work async by default and running in Task is like calling different thread to do job in already separated thread so continue method will not work as expected. I faced with this issue while I was working with editing Bitmaps ( not about Glide at this point ). Call Glide directly without await and see result. I am not sure if it works since you're not able to listen but give it a try.

bgillman22 commented 7 years ago

Actually, task/continue works fine but only when I set override to specific values. For example: .Override(Width, Height) .Into(Width, Height) // calculated values, does not work .Override(Width + 1, Height + 1) .Into(Width, Height) // does not work .Override(200, 200) .Into(Width, Height) // does work but looks small .Override(Width, Height) .Into(Width, Height) // does work but looks small

I guess I just need to learn what these numbers mean and how to calculate values that allow my image to look right at any resolution.

bgillman22 commented 7 years ago

I found a different way to do it. Instead of using override, I just set the size manually. Thanks for your help!

var target = Glide.With(Activity) .Load(frame.Id) .CenterCrop() .Into(Width, Height) .Get(); var drawable = (Com.Bumptech.Glide.Load.Resource.Drawable.GlideDrawable)target; return drawable.Mutate();