Reputation: 116010
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:
I'm finding difficulties finding the correct functions and parameters to make it generate the proper width&height of the output bitmap.
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.
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?
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?
Upvotes: 0
Views: 842
Reputation: 116010
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()
}
Upvotes: 0
Reputation: 416
- I should scale/crop so that the height will be of a specific value.
- The width should be at least of a specific value
- Keep the aspect ratio no matter what.
You can't really hold all of these to be true, because if you have a guaranteed minimum height and a guaranteed minimum width, then you might have to distort the aspect ratio, which violates the third condition.
I'd recommend having these three conditions instead:
Glide can do 1 and 3 for you but 2 you might need to first decode the bitmap without allocating memory (look at BitmapFactory.Options.inJustDecodeBounds
) to get the source aspect ratio then use math to figure out what height and width to set so you don't go over your per-bitmap memory ceiling.
Last thing though, depending on your use case (if you need to render multiple bitmaps in a short amount of time), you might want to consider cropping to a standard output aspect ratio so you can take advantage of Glide's bitmap recycling feature, which helps avoid OOM crashes.
Upvotes: 0