首页 > 编程语言 >Glide源码阅读之策略模式2【DownsampleStrategy】

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

时间:2023-09-19 12:08:38浏览次数:36  
标签:CENTER Glide int 源码 尺寸 DownsampleStrategy sourceHeight sourceWidth


策略模式二

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.
 *
 * <p>{@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}.
 *
 * <p>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.
 *
 * <p>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.
   *
   * <p>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.
   *
   * <p>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.
   *
   * <p>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}.
   *
   * <p>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 <em>NOT</em> 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.
   *
   * <p>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}.
   *
   * <p>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<DownsampleStrategy> 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.
   *
   * <p>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.
   *
   * <p>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 << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0);
      return 1f / greaterOrEqualSampleSize;
    }

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

FIT_CENTER

缩放,保持原始的宽高比,以便其中一个图像的尺寸完全等于请求的尺寸,而另一个尺寸小于或等于请求的尺寸。
如果请求的宽度和高度大于源的宽度和高度,则此方法将升级。为了避免升级,请使用AT_LEAST、AT_MOST或CENTER_INSIDE。

在kitkat之前的设备上,FIT_CENTER将只向下采样2次幂,以便其中一个图像的尺寸大于或等于请求的尺寸。对于第二个维度没有任何保证。这与AT_LEAST不同,因为只有一个维度大于或等于请求的维度,而不是两个维度都大于或等于请求的维度,另一个维度可能更小。

private static class FitCenter extends DownsampleStrategy {

    @Synthetic
    FitCenter() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      if (IS_BITMAP_FACTORY_SCALING_SUPPORTED) {
        float widthPercentage = requestedWidth / (float) sourceWidth;
        float heightPercentage = requestedHeight / (float) sourceHeight;

        return Math.min(widthPercentage, heightPercentage);
      } else {
        // Similar to AT_LEAST, but only require one dimension or the other to be >= requested
        // rather than both.
        int maxIntegerFactor =
            Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth);
        return maxIntegerFactor == 0 ? 1f : 1f / Integer.highestOneBit(maxIntegerFactor);
      }
    }

    @Override
    public SampleSizeRounding getSampleSizeRounding(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      if (IS_BITMAP_FACTORY_SCALING_SUPPORTED) {
        return SampleSizeRounding.QUALITY;
      } else {
        // TODO: This doesn't seem right, but otherwise we can skip a sample size because QUALITY
        // prefers the smaller of the width and height scale factor. MEMORY is a hack that
        // lets us prefer the larger of the two.
        return SampleSizeRounding.MEMORY;
      }
    }
  }

CENTER_INSIDE

与FIT_CENTER相同,但从未升级

private static class CenterInside extends DownsampleStrategy {

    @Synthetic
    CenterInside() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {

      return Math.min(
          1.f,
          FIT_CENTER.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight));
    }

    @Override
    public SampleSizeRounding getSampleSizeRounding(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      return getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight) == 1.f
          ? SampleSizeRounding.QUALITY
          : FIT_CENTER.getSampleSizeRounding(
              sourceWidth, sourceHeight, requestedWidth, requestedHeight);
    }
  }

CENTER_OUTSIDE

缩放,保持原始的宽高比,以便其中一个图像的尺寸完全等于请求的尺寸,而另一个尺寸大于或等于请求的尺寸。
如果请求的宽度和高度大于源的宽度和高度,则此方法将升级。为了避免升级,请使用AT_LEAST、AT_MOST或CENTER_INSIDE。

在KitKat 之前的设备上,Downsampler将其视为等同于AT_LEAST,因为只能使用两次下采样的幂次

private static class CenterOutside extends DownsampleStrategy {

    @Synthetic
    CenterOutside() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      float widthPercentage = requestedWidth / (float) sourceWidth;
      float heightPercentage = requestedHeight / (float) sourceHeight;
      return Math.max(widthPercentage, heightPercentage);
    }

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

NONE

不进行下采样或缩放。

private static class None extends DownsampleStrategy {

    @Synthetic
    None() {}

    @Override
    public float getScaleFactor(
        int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
      return 1f;
    }

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

DEFAULT= CENTER_OUTSIDE(见CENTER_OUTSIDE)

默认采集策略

自研产品推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。

嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!

下面是一段smartApi使用介绍:

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

下载地址:

https://pan.baidu.com/s/1kFAGbsFIk3dDR64NwM5y2A?pwd=csdn


标签:CENTER,Glide,int,源码,尺寸,DownsampleStrategy,sourceHeight,sourceWidth
From: https://blog.51cto.com/u_16264967/7523917

相关文章

  • Glide源码阅读之工厂模式4总结
    工厂模式的应用比较多;变化形态也是各种各样。但经过这段时间的解读。大概可以用浓缩为1、不是使用new创建对象;2、没有明显build方法创建对象;3、带xxxFactory的几乎都满足工厂模式。当然第3点比较明显。如果不带xxxFactory等这样的标识那看看是否有implements、extends。而且内......
  • Glide源码阅读之状态模式[SingleRequest<R>.Status]
    前言前面写完策略模式,接着写状态模式;在开始接触这两个模式的时候我也很疑惑,这两个设计模式很相似,用法也很类似。好一段时间我都没有区分这两者的区别。在使用的时候也不知道怎么选择,后来慢慢的加深理解也就总结出规律了。先看看状态模式的经典结构状态模式介绍《Android源码设计模......
  • Glide源码阅读之策略模式4总结
    《Android源码设计模式解析与实践》定义策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化使用场景针对同一类型问题的多种处理方式。仅仅是具体行为有差别时需要安全地封装多种同一类型的操作时出现同一抽......
  • Glide源码阅读之工厂模式2【DiskCache.Factory】
    DiskCache.Factory包路径:com.bumptech.glide.load.engine.cache.DiskCachecom.bumptech.glide.load.engine.cache.DiskCache.Factory/**Aninterfaceforwritingtoandreadingfromadiskcache.*/一种向磁盘缓存写入和从磁盘缓存读取数据的接口。publicinterfaceDiskCa......
  • Glide源码阅读之工厂模式1【ModelLoaderFactory】【ModelLoader】
    使用场景介绍摘自菜鸟教程|设计模式|工厂模式意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。主要解决:主要解决接口选择的问题。何时使用:我们明确地计划不同条件下创建不同实例时。如何解决:让其子类实现工厂接口,返回的也是一个......
  • Glide源码阅读之建造者(builder)模式3【RequestOptions】【BaseRequestOptions】
    官方定义本来解析完GlideBuilder、RequestBuilder就已经觉得建造者模式用的变化有些大了,但随着解析的进行发现还要下面的这两种变种应用。先解析出来给大家看看,说不定在某些场景下能启发读者使用这种模式应用方式builder模式应用变化一结构:publicstaticRequestOptionssizeXXXX(p......
  • 万字长文深度解读Java线程池,硬核源码分析
    前言本文将深入分析Java线程池的源码,包括线程池的创建、任务提交、工作线程的执行和线程池的关闭等过程。通过对线程池源码的解析,我们能够更好地理解线程池的原理和机制,为我们在实际开发中合理使用线程池提供指导。文章内容较长,建议找个安静的环境慢慢细读,由于线程池涉及的内容......
  • 云HIS医院信息化管理系统源码:集团化管理,多租户机制,满足医院业务需求
    随着云计算、大数据、物联网等新兴技术的迅猛发展,HIS模式的理念、运行机制更新,衍生出了新的HIS模式——云HIS。云HIS是基于云计算、大数据、互联网等高新技术研发的医疗卫生信息平台,它实现了医院信息化从局域网向互联网转型,并重新定义了医疗卫生信息化建设的理念、框架、功能以及运......
  • qemu源码分析(6)--Apple的学习笔记
    一,前言由于看到了类似的写法,都用到了object_dynamic_cast_assert函数,所以分析下。二,源码分析看到如下代码的写法,很眼熟CortexMBoardState*board=CORTEXM_BOARD_STATE(machine);machine的类型是MachineState*#defineCORTEXM_BOARD_STATE(obj)\OBJECT_CHECK(CortexMBoardSt......
  • 如何给OpenWrt的源码打patch
    如何给OpenWrt的源码打patch目录如何给OpenWrt的源码打patch给package打patch给kernel打patch给package打patchOpenWrt有成熟的打patch机制,可以直接从服务器download源码,校验后,再结合自己开发的patch,打上,然后编译。开发环境:基于Ubuntu14.0432bit主机,编译demo_board机型。需......