Glide探究一 如何計算載入後的圖片尺寸?
阿新 • • 發佈:2018-11-13
Glide探究一 如何計算載入後的圖片尺寸?
一、疑問
- 呼叫
RequestBuilder
into(@NonNull ImageView view)
,載入後的圖片尺寸是多少? - 呼叫
RequestBuilder
into(@NonNull Y target)
- 呼叫
RequestOptions
override(int width, int height)
,載入後的圖片尺寸是多少?
二、請求尺寸
無論使用何種方式載入圖片,Glide
首先計算request
請求尺寸。請求尺寸可以在2個地方進行設定。
Target
RequestOptions
通過RequestBuilder
into(@NonNull ImageView view)
,實質上是通過Target
實現的,確切地說是BitmapImageViewTarget
或者DrawableImageViewTarget
。Target
SIZE_ORIGINAL
用於將請求尺寸設定為圖片尺寸。
int SIZE_ORIGINAL = Integer.MIN_VALUE;
其次,可以在RequestOptions
中通過override(int width, int height)
覆蓋Target
地請求尺寸。
三、三種尺寸
- request請求尺寸(在
Target
或者RequestOptions
中設定的尺寸) - source源圖片尺寸(圖片自身尺寸)
- target目標尺寸(載入後的圖片尺寸)
上一部分中,我們已經知道如何設定Glide
的request
請求尺寸,並且圖片的自身的source
request
和source
兩種尺寸計算出最終的target
大小?答案是DownsampleStrategy
。
四、DownsampleStrategy
DownsampleStrategy
定義了2個抽象方法
public abstract float getScaleFactor(
int sourceWidth, int sourceHeight,
int requestedWidth, int requestedHeight);
public abstract SampleSizeRounding getSampleSizeRounding(
int sourceWidth, int sourceHeight,
int requestedWidth, int requestedHeight);
getScaleFactor
根據source
和request
大小計算出縮放比例來確定target
尺寸。
getSampleSizeRounding
用於計算inSampleSize
的數值,SampleSizeRounding
有2個列舉值。
MEMORY
記憶體優先,增加inSampleSize
值,保證較小的記憶體使用。QUALITY
質量優先,降低inSampleSize
值,保證較高的圖片質量。
由DownsampleStrategy
的定義可以看出,Glide
載入後的圖片保持了原始比例。
五、BitmapFactory.Options
通過DownsmapleStrategy
的getScaleFactor
方法,計算出scaleFactor
縮放比例。從而計算出最終的target
尺寸。
targetWidth = sourceWidth * scaleFactor;
targetHeight = sourceHeight * scaleFactor;
接下來通過BitmapFactory
載入圖片即可。與載入圖片相關的幾個重要引數
public boolean inJustDecodeBounds; // 僅解碼圖片尺寸,並不載入圖片
public Bitmap inBitmap; // 複用已有的Bitmap,Glide總是優先使用inBitmap複用圖片
public int inSampleSize; // 取樣大小,必須是2的指數,<= 1,2,4,8,16,……
public boolean inScaled; // 縮放,結合inTargetDensity和inDensity確定最終圖片大小
public int inTargetDensity; // 目標Density
public int inDensity; // 源Density
BitmapFactory.Options
幾個引數對載入後Bitmap
尺寸的影響。
// inScaled = false,inTargetDensity = inDensity = 0時
// 取樣值越大,得到的Bitmap尺寸越小
bitmap.width = sourceWidth / inSampleSize;
bitmap.height = sourceHeight / inSampleSize;
// 同時對圖片進行縮放
bitmap.width = sourceWidth / inSampleSize * inTargetDensity / inDensity;
bitmap.height = sourceHeight / inSampleSize * inTargetDensity / inDensity;
六、Downsampler
Downsampler
完成了圖片的載入過程。
public Resource<Bitmap> decode(
InputStream is,
int requestedWidth, int requestedHeight,
Options options,
DecodeCallbacks callbacks) throws IOException; // 注意request大小
private Bitmap decodeFromWrappedStreams(
InputStream is,
BitmapFactory.Options options,
DownsampleStrategy downsampleStrategy,
DecodeFormat decodeFormat, boolean isHardwareConfigAllowed,
int requestedWidth, int requestedHeight,
boolean fixBitmapToRequestedDimensions,
DecodeCallbacks callbacks) throws IOException; // 出現了downsampleStrategy
private static void calculateScaling(
ImageType imageType,
InputStream is,
DecodeCallbacks decodeCallbacks,
BitmapPool bitmapPool,
DownsampleStrategy downsampleStrategy,
int degreesToRotate,
int sourceWidth,
int sourceHeight,
int targetWidth,
int targetHeight,
BitmapFactory.Options options) throws IOException; // target大小已經確定
七、RequestOptions
RequestOptions
中設定request
尺寸及DownsampleStrategy
public RequestOptions override(int width, int height);
public RequestOptions downsample(@NonNull DownsampleStrategy strategy);
八、總結
BitmapFactory.Options
的4個引數inSampleSize
,inScaled
,inTargetDensity
,inDensity
共同決定了載入後的bitmap
大小;DownsampleStrategy
計算request
及source
尺寸的縮放比例,進而計算出BitmapFactory.Options
的最終引數;RequestOptions
中設定request
大小及DownsampleStrategy
;Downsampler
完成了所以計算工作,並完成載入圖片的工作;