Search code examples
androidbitmapscalecropandroid-glide

Using Glide, is it possible to get output image resolution, before the actual decoding and saving into a bitmap?


Background

I'm trying to have a horizontally scrolling effect on any given image file in a live wallpaper app.

For this, I should work according to these rules, I think:

  • Input is an image file of any resolution
  • I should scale/crop so that the height will be of a specific value.
  • The width should be at least of a specific value
  • Output bitmap should be up to a certain width, because I don't want to make a too large bitmap, taking huge amount of memory
  • Keep the aspect ratio no matter what.

The problem

I'm finding difficulties finding the correct functions and parameters to make it generate the proper width&height of the output bitmap.

What I've tried

I've tried messing around with various transformations (example: centerCropTransform,fitCenterTransform) , but none of those reached what I wanted, so I think that none can work unless I do some special math on my side before deciding what to do with Glide.

Currently what I do is something like that:

val result = Glide.with(context).asBitmap()
                           .load(imageFile)
                           .apply(RequestOptions.noTransformation()
                           .skipMemoryCache(true)
                           .diskCacheStrategy(DiskCacheStrategy.NONE))
                           .submit(reqWidth, reqHeight).get()

This works, as it produces (at least according to my tests) a bitmap that is at least of the size I request it to be. However, it means I have extra pixels that aren't really needed for the height. It also doesn't protect me from generating a too large bitmap.

But I think maybe it would be easier to ask Glide to use various techniques for the above purpose, and then decide on the possible output resolutions, which is the best to use.

The questions

  1. Is it possible to get the output resolution before the actual decoding&storing into a bitmap, and only later decide which technique should be used?

  2. Is there maybe a better option I should consider ? Maybe do the calculation on my side, and then decide what to do with Glide? If so, how?


Solution

  • OK I think I got it.

    I calculate what will happen if I fit to width and to height, and use center crop on the calculated result accordingly:

                        val bitmapOptions = Utils.getBitmapOptions(savedImageFileForWallpaperBackground.absolutePath)
                        //newWidth/newHeight=oldWidth/oldHeight
                        val widthIfScaledToHeight = reqHeight * bitmapOptions.outWidth / bitmapOptions.outHeight
                        val heightIfScaledToWidth = reqWidth * bitmapOptions.outHeight / bitmapOptions.outWidth
    
                        val result: Bitmap
                        if (widthIfScaledToHeight >= reqWidth) {
                            result = Glide.with(wallpaperService).asBitmap()
                                    .load(savedImageFileForWallpaperBackground)
                                    .apply(RequestOptions.centerCropTransform().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE))
                                    .submit(widthIfScaledToHeight, reqHeight).get()
                        } else {
                            result = Glide.with(wallpaperService).asBitmap()
                                    .load(savedImageFileForWallpaperBackground)
                                    .apply(RequestOptions.centerCropTransform().skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE))
                                    .submit(reqWidth, heightIfScaledToWidth).get()
                        }