您当前的位置: 首页 >  ide

lichong951

暂无认证

  • 2浏览

    0关注

    131博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Glide源码阅读之策略模式2【DownsampleStrategy】

lichong951 发布时间:2022-01-10 14:00:56 ,浏览量:2

策略模式二

DownsampleStrategy

包路径:com.bumptech.glide.load.resource.bitmap.DownsampleStrategy

指示对图像进行下采样时使用的算法。 DownsampleStrategy不提供任何关于输出大小的保证。行为将不同,取决于ResourceDecoder使用的策略和Android版本的代码运行。使用DownsampleStrategy作为优化,只提高内存效率。如果你需要一个特定的尺寸或形状输出,使用Transformation来代替或补充DownsampleStrategy。

下面列出了Android和ResourceDecoders版本之间的一些差异,但这个列表并不全面,因为DownsampleStrategy只控制其输出比例值,而不是如何使用该输出值。

在某些版本的Android上,精确的缩放是不可能的。在这种情况下,由于只支持两次下采样的幂次,所以策略只能在下采样到请求大小的1倍和请求大小的2倍之间,以及0.5倍的请求大小和1倍的请求大小之间进行选择。为了保持转换的潜力,精确缩放而不损失质量,除了AT_MOST之外,所有人都倾向于将样本缩小到请求大小的1倍到2倍之间。


/**
 * Indicates the algorithm to use when downsampling images.
 *
 * 

{@code DownsampleStrategy} does not provide any guarantees about output sizes. Behavior will * differ depending on the {@link com.bumptech.glide.load.ResourceDecoder} using the strategy and * the version of Android the code runs on. Use {@code DownsampleStrategy} as an optimization to * improve memory efficiency only. If you need a particular size or shape output, use an {@link * com.bumptech.glide.load.Transformation} either instead or in addition to a {@code * DownsampleStrategy}. * *

Some differences between versions of Android and {@link * com.bumptech.glide.load.ResourceDecoder}s are listed below, but the list is not comprehensive * because {@link DownsampleStrategy} only controls its output scale value, not how that output * value is used. * *

On some versions of Android, precise scaling is not possible. In those cases, the strategies * can only pick between downsampling to between 1x the requested size and 2x the requested size and * between 0.5x the requested size and 1x the requested size because only power of two downsampling * is supported. To preserve the potential for a {@link com.bumptech.glide.load.Transformation} to * scale precisely without a loss in quality, all but {@link #AT_MOST} will prefer to downsample to * between 1x and 2x the requested size. */ // Public API. @SuppressWarnings("WeakerAccess") public abstract class DownsampleStrategy { /** * Downsamples so the image's smallest dimension is between the given dimensions and 2x the given * dimensions, with no size restrictions on the image's largest dimension. * *

Does not upscale if the requested dimensions are larger than the original dimensions. */ 下采样使图像的最小尺寸介于给定尺寸和给定尺寸的2倍之间,而对图像的最大尺寸没有尺寸限制。 如果所要求的尺寸比原始尺寸大,则不需要升级。 public static final DownsampleStrategy AT_LEAST = new AtLeast(); /** * Downsamples so the image's largest dimension is between 1/2 the given dimensions and the given * dimensions, with no restrictions on the image's smallest dimension. * *

Does not upscale if the requested dimensions are larger than the original dimensions. */ 下采样使得图像的最大尺寸在给定尺寸和给定尺寸的1/2之间,对图像的最小尺寸没有限制。 如果所要求的尺寸比原始尺寸大,则不需要升级。 public static final DownsampleStrategy AT_MOST = new AtMost(); /** * Scales, maintaining the original aspect ratio, so that one of the image's dimensions is exactly * equal to the requested size and the other dimension is less than or equal to the requested * size. * *

This method will upscale if the requested width and height are greater than the source width * and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST} or {@link * #CENTER_INSIDE}. * *

On pre-KitKat devices, {@code FIT_CENTER} will downsample by a power of two only so that one * of the image's dimensions is greater than or equal to the requested size. No guarantees are * made about the second dimensions. This is NOT the same as {@link #AT_LEAST} because * only one dimension, not both, are greater than or equal to the requested dimensions, the other * may be smaller. */ 缩放,保持原始的宽高比,以便其中一个图像的尺寸完全等于请求的尺寸,而另一个尺寸小于或等于请求的尺寸。 如果请求的宽度和高度大于源的宽度和高度,则此方法将升级。为了避免升级,请使用AT_LEAST、AT_MOST或CENTER_INSIDE。 在kitkat之前的设备上,FIT_CENTER将只向下采样2次幂,以便其中一个图像的尺寸大于或等于请求的尺寸。对于第二个维度没有任何保证。这与AT_LEAST不同,因为只有一个维度大于或等于请求的维度,而不是两个维度都大于或等于请求的维度,另一个维度可能更小。 public static final DownsampleStrategy FIT_CENTER = new FitCenter(); /** Identical to {@link #FIT_CENTER}, but never upscales. */ 与FIT_CENTER相同,但从未升级 public static final DownsampleStrategy CENTER_INSIDE = new CenterInside(); /** * Scales, maintaining the original aspect ratio, so that one of the image's dimensions is exactly * equal to the requested size and the other dimension is greater than or equal to the requested * size. * *

This method will upscale if the requested width and height are greater than the source width * and height. To avoid upscaling, use {@link #AT_LEAST}, {@link #AT_MOST}, or {@link * #CENTER_INSIDE}. * *

On pre-KitKat devices, {@link Downsampler} treats this as equivalent to {@link #AT_LEAST} * because only power of two downsampling can be used. */ 缩放,保持原始的宽高比,以便其中一个图像的尺寸完全等于请求的尺寸,而另一个尺寸大于或等于请求的尺寸。 如果请求的宽度和高度大于源的宽度和高度,则此方法将升级。为了避免升级,请使用AT_LEAST、AT_MOST或CENTER_INSIDE。 在KitKat 之前的设备上,Downsampler将其视为等同于AT_LEAST,因为只能使用两次下采样的幂次。 public static final DownsampleStrategy CENTER_OUTSIDE = new CenterOutside(); /** Performs no downsampling or scaling. */ 不进行下采样或缩放。 public static final DownsampleStrategy NONE = new None(); /** Default strategy, currently {@link #CENTER_OUTSIDE}. */ 默认策略,当前为CENTER_OUTSIDE。 public static final DownsampleStrategy DEFAULT = CENTER_OUTSIDE; /** * Indicates the {@link com.bumptech.glide.load.resource.bitmap.DownsampleStrategy} option that * will be used to calculate the sample size to use to downsample an image given the original and * target dimensions of the image. */ 指示DownsampleStrategy选项,该选项将用于计算在给定图像的原始和目标尺寸的情况下对图像进行下采样的样本大小。 // The exact String value here is retained to avoid breaking cache keys for images that were // loaded with older versions of Glide. public static final Option OPTION = Option.memory( "com.bumptech.glide.load.resource.bitmap.Downsampler.DownsampleStrategy", DEFAULT); @Synthetic static final boolean IS_BITMAP_FACTORY_SCALING_SUPPORTED = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; /** * Returns a float (0, +infinity) indicating a scale factor to apply to the source width and * height when displayed in the requested width and height. * *

The returned scale factor will be split into a power of two sample size applied via {@link * android.graphics.BitmapFactory.Options#inSampleSize} and a float scale factor applied after * downsampling via {@link android.graphics.BitmapFactory.Options#inTargetDensity} and {@link * android.graphics.BitmapFactory.Options#inDensity}. Because of rounding errors the scale factor * may not be applied precisely. * *

The float scaling factor will only be applied on KitKat+. Prior to KitKat, only the power of * two downsampling will be applied. * * @param sourceWidth The width in pixels of the image to be downsampled. * @param sourceHeight The height in pixels of the image to be downsampled. * @param requestedWidth The width in pixels of the view/target the image will be displayed in. * @param requestedHeight The height in pixels of the view/target the image will be displayed in. */ 返回一个浮点数(0,+∞),指示在请求的宽度和高度中显示时应用于源宽度和高度的比例因子。 返回的比例因子将被拆分为两个样本大小的幂,通过BitmapFactory.Options.inSampleSize应用,并通过BitmapFactory.Options.inTargetDensity和BitmapFactory.Options.inDensity应用下采样后的浮动比例因子。由于舍入误差,比例因子可能不能精确地应用。 浮动缩放因子将只适用于KitKat+。在KitKat之前,只会使用两次下采样的功率。 参数: sourceWidth -要下采样的图像的像素宽度。 sourceHeight -要下采样的图像的像素高度。 requestedWidth -图像将显示在视图/目标的像素宽度。 requestdheight -图像将显示的视图/目标的像素高度。 public abstract float getScaleFactor( int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight); /** * Returns a non-null {@link SampleSizeRounding} to use to resolve rounding errors and conflicts * between scaling for the width and the height of the image. * * @param sourceWidth The width in pixels of the image to be downsampled. * @param sourceHeight The height in pixels of the image to be downsampled. * @param requestedWidth The width in pixels of the view/target the image will be displayed in. * @param requestedHeight The height in pixels of the view/target the image will be displayed in. */ 返回一个非空的DownsampleStrategy。SampleSizeRounding用来解决舍入误差和图像的宽度和高度缩放之间的冲突。 参数: sourceWidth -要下采样的图像的像素宽度。 sourceHeight -要下采样的图像的像素高度。 requestedWidth -图像将显示在视图/目标的像素宽度。 requestdheight -图像将显示的视图/目标的像素高度。 public abstract SampleSizeRounding getSampleSizeRounding( int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight); /** * Indicates whether to prefer to prefer downsampling or scaling to prefer lower memory usage or * higher quality. */ 指示是倾向于向下采样还是缩放倾向于更低的内存使用或更高的质量。 public enum SampleSizeRounding { /** * Prefer to round the sample size up so that the image is downsampled to smaller than the * requested size to use less memory. */ 更喜欢将样本大小取整,以便将图像向下采样到比请求的大小更小的大小,从而使用更少的内存。 MEMORY, /** * Prefer to round the sample size down so that the image is downsampled to larger than the * requested size to maintain quality at the expense of extra memory usage. */ 更倾向于将采样大小取整,以便将图像采样到大于请求的大小,以保持质量,但要牺牲额外的内存使用。 QUALITY, }

策略实现列表如下:
  1. AT_LEAST
  2. AT_MOST
  3. FIT_CENTER
  4. CENTER_INSIDE
  5. CENTER_OUTSIDE
  6. NONE
  7. DEFAULT= CENTER_OUTSIDE;
AT_LEAST

下采样使图像的最小尺寸介于给定尺寸和给定尺寸的2倍之间,而对图像的最大尺寸没有尺寸限制。 如果所要求的尺寸比原始尺寸大,则不需要升级。


  private static class AtLeast extends DownsampleStrategy {

    @Synthetic
    AtLeast() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      int minIntegerFactor = Math.min(sourceHeight / requestedHeight, sourceWidth / requestedWidth);
      return minIntegerFactor == 0 ? 1f : 1f / Integer.highestOneBit(minIntegerFactor);
    }

    @Override
    public SampleSizeRounding getSampleSizeRounding(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      return SampleSizeRounding.QUALITY;
    }
  }

AT_MOST

下采样使得图像的最大尺寸在给定尺寸和给定尺寸的1/2之间,对图像的最小尺寸没有限制。 如果所要求的尺寸比原始尺寸大,则不需要升级。

private static class AtMost extends DownsampleStrategy {

    @Synthetic
    AtMost() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      int maxIntegerFactor =
          (int)
              Math.ceil(
                  Math.max(
                      sourceHeight / (float) requestedHeight,
                      sourceWidth / (float) requestedWidth));
      int lesserOrEqualSampleSize = Math.max(1, Integer.highestOneBit(maxIntegerFactor));
      int greaterOrEqualSampleSize =
          lesserOrEqualSampleSize             
关注
打赏
1659512212
查看更多评论
0.1982s