Hot questions for Using Glide in touchimageview

Top 10 Java Open Source / Glide / touchimageview

Question:

I'm trying to load a large hi-res (3225x4800) image from URL into glide for a newspaper company. The image I wanted to load is this High Res Image.

String url = "http://www.businessweekmindanao.com/content/wp-content/uploads/2015/10/fitness-and-wellness-poster-final.jpg";

Glide.with(getActivity()).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
        imageView.setImageBitmap(resource);
    }
});

I'm using Mike Ortiz' TouchImageView from the solution offered here: https://github.com/MikeOrtiz/TouchImageView/issues/135 when loading resource from url. But it seems to only work on small resolution image and it does not load high quality image.

There is an alternative solution I tried from stackoverflow: Android: not displayed ImageView with UIL and TouchImageView which tries to modify the onMeasure() method of Mike's library. It works with:

Glide.with(getActivity()).load(url)
                .into(imageViewPreview);

The problem is it loads the image in very low resolution.

Is there a way to load high resolution image like: 7480x3740 for instance using Glide and TouchImageView? How do I do that?


Answer:

I have found a solution that worked for my requirement. The override() method does the trick. Setting higher numbers for the target resolution seems to be the final workaround, but the bigger the numbers, the longer the time it would take to display the image(s), so it would be wise to implement a preloader/progressbar.

Glide.with(getContext())
    .asBitMap() //[for new glide versions]
    .load(url)
    //.asBitmap()[for older glide versions]
    //.placeholder(R.drawable.default_placeholder)
    .override(1600, 1600) // Can be 2000, 2000
    .into(new BitmapImageViewTarget(imageViewPreview) {
        @Override
        public void onResourceReady(Bitmap  drawable, GlideAnimation anim) {
            super.onResourceReady(drawable, anim);
            progressBar.setVisibility(View.GONE);
        }
    });

Custom centered preloader/progressbar placeholder indicator on relativeLayout xml:

<ProgressBar
    android:id="@+id/progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" />

This is neat because another issue related about loading image asBitmap() in Glide will not show placeholders for error and preloader/progress indicator:

Glide.with(getActivity())
    .load(url).asBitmap()
    .placeholder() //<== will simply not work:
    .error() // <== is also useless
    .into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
        imageView.setImageBitmap(resource);
    }
});

In my research, I have also tried a Picasso solution to handle high quality image:

Picasso.with(getContext())
                .load(url)
                .resize(1500, 0)
                .placeholder(R.drawable.default_placeholder)
                .error(R.drawable.download_error)
                .into(imageViewPreview);

In the end, I was happy with the Glide version.

I hope this will be helpful to anyone that might be facing the same challenge.

Question:

What I want to accomplish is to load an image into TouchImageView (https://github.com/MikeOrtiz/TouchImageView) with glide using default size (view's size) and then on zoom I would like to replace the bitmap with higher res.

My approach:

 lang-java
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    imageView.setOnTouchImageViewListener {
        if (!zoomedIn && imageView.currentZoom == MAX_ZOOM) {
            zoomedIn = true
            loadImage(uri, Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
        }
    }

    loadImage(uri)
}

private fun loadImage(uri: Uri, width: Int = 0, height: Int = 0) {
    Glide.with(context)
            .asBitmap()
            .load(uri)
            .let {
                if (width == 0 && height == 0) {
                    it
                } else {
                    it.override(width, height)
                }
            }
            .centerInside()
            .into(imageView)
}

The implementation causes the ImageView to display black background when higher res image is being loaded. I assume it is because Glide is releasing resources on each load (I am pretty sure I found this in the documentation).

Is there a way to prevent it in this particular scenario?

I do not want use Thumbnail feature for the above purpose as it will load high res image every time for every image (I would prefer to do it only on zoom for user to actually benefit from additional details of the image).

Maybe there is a totally different approach that I am not seeing?


Answer:

Solution is actually fairly simple.

Just use two TouchImageViews (iv, ivhighres) and replace them once the high res image is loaded.

You can user ViewSwitcher (as Documentation suggests) if you would like to animate the change.

Note that you need to call ivhighres.setZoom(iv) for the zoom properties to be mirrored from the low res image to the high res image.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    iv.setOnTouchImageViewListener {
        ivhighres.setZoom(iv)
        if (!zoomedIn && imageView.currentZoom == MAX_ZOOM) {
            zoomedIn = true
            loadImageHighRes(uri)
        }
    }

    loadImage(uri)
}

private fun loadImage(uri: Uri) {
    Glide.with(context)
            .asBitmap()
            .load(uri)
            .centerInside()
            .into(iv)
}

private fun loadImageHighRes(uri: Uri) {
    Glide.with(context)
            .asBitmap()
            .load(uri)
            .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
            .centerInside()
            .into(object : CustomViewTarget<TouchImageView, Bitmap>(ivhighres) {
                    override fun onLoadFailed(errorDrawable: Drawable?) {
                    }

                    override fun onResourceCleared(placeholder: Drawable?) {
                        ivhighres?.setImageDrawable(placeholder)
                    }

                    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                        ivhighres?.setImageBitmap(resource)
                        ivhighres?.visibility = View.VISIBLE
                        iv?.visibility = View.GONE
                    }

                })
}