使用Glide,是否可以在实际解码并保存到位图中之前获得输出图像的分辨率?

时间:2019-01-01 18:03:04

标签: android bitmap scale crop android-glide

背景

我正在尝试对动态壁纸应用中的任何给定图像文件进行水平滚动效果。

为此,我认为应该按照以下规则进行工作:

  • 输入是任何分辨率的图像文件
  • 我应该缩放/裁剪以便高度达到特定值。
  • 宽度至少应为特定值
  • 输出位图应达到一定的宽度,因为我不想制作太大的位图,占用大量内存
  • 无论如何保持宽高比。

问题

我发现很难找到正确的函数和参数,以使其生成正确的输出位图宽度和高度。

我尝试过的

我尝试弄乱各种转换(例如:centerCropTransform,fitCenterTransform),但是这些转换都没有达到我想要的,所以我认为除非我在决定做什么之前先做一些特殊的数学运算,否则这些转换都无法正常工作。使用Glide。

目前我正在做的事情是这样的:

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

这有效,因为它(至少根据我的测试)产生的位图至少应达到我要求的大小。但是,这意味着我还有一些高度实际上并不需要的像素。这也不能保护我不要生成太大的位图。

但是我认为,也许要求Glide为上述目的使用各种技术,然后决定可能的输出分辨率,这是最好的选择,会更容易。

问题

  1. 是否有可能在实际解码和存储为位图之前获得输出分辨率,并且仅在以后决定应使用哪种技术?

  2. 是否应该考虑一个更好的选择?也许是在我这边做计算,然后决定如何处理Glide?如果是这样,怎么办?

2 个答案:

答案 0 :(得分:0)

  
      
  • 我应该缩放/裁剪以便高度达到特定值。
  •   
  • 宽度至少应为特定值
  •   
  • 无论如何保持宽高比。
  •   

您不能真正地将所有这些都说成是真的,因为如果您具有保证的最小高度和保证的最小宽度,那么您可能不得不扭曲长宽比,这违反了第三个条件。

我建议改用以下三个条件:

  1. 将输出的最大高度设置为设备屏幕的高度(纵向)
  2. 设置输出位图的最大已分配内存
  3. 无论如何保持原始长宽比

Glide可以为您做1和3,但是您可能需要先解码位图而不分配内存(请看BitmapFactory.Options.inJustDecodeBounds)才能获得源长宽比,然后使用数学算出要计算的高度和宽度是2设置,这样就不会超过每个位图的内存上限。

最后,根据使用情况(如果需要在短时间内渲染多个位图),您可能需要考虑裁剪到标准输出宽高比,以便可以利用Glide的位图回收功能,这有助于避免OOM崩溃。

答案 1 :(得分:0)

好吧,我想我明白了。

我计算出适合宽度和高度的情况,然后在计算结果上使用中心裁切:

                    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()
                    }