/* * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package me.xiaopan.sketch.request; import android.graphics.Bitmap; import android.text.TextUtils; import me.xiaopan.sketch.decode.ImageType; import me.xiaopan.sketch.process.ImageProcessor; import me.xiaopan.sketch.util.SketchUtils; /** * 加载选项,适用于 {@link me.xiaopan.sketch.Sketch#load(String, LoadListener)} 方法 */ public class LoadOptions extends DownloadOptions { /** * 修正尺寸 */ private Resize resize; /** * 强制使经过resize处理的图片同resize的尺寸一致 */ private boolean forceUseResize; /** * 最大尺寸,用于计算inSampleSize,缩小图片 */ private MaxSize maxSize; /** * 解码GIF图片 */ private boolean decodeGifImage; /** * 在解码或创建Bitmap的时候尽量使用低质量的Bitmap.Config * * @see ImageType */ private boolean lowQualityImage; /** * 解码时优先考虑速度还是质量 (true:质量;false:速度,默认false),优先级比 bitmapConfig 低 * * @see #bitmapConfig */ private boolean inPreferQualityOverSpeed; /** * 开启缩略图模式,当resize的宽高比同原始图片的宽高比相差非常大的时候会用BitmapRegionDecoder从原始图片中截取合适的部分,这样对于现实较大图片的缩略图会有很大的帮助 */ private boolean thumbnailMode; /** * 图片处理器 */ private ImageProcessor imageProcessor; /** * 图片质量配置,优先级比 lowQualityImage 高 * * @see #lowQualityImage */ private Bitmap.Config bitmapConfig; /** * 为了加快显示速度,将经过ImageProcessor、resize或thumbnailMode处理过的图片保存到磁盘缓存中,下次就直接读取 */ private boolean cacheProcessedImageInDisk; /** * 禁止从BitmapPool中寻找可复用的Bitmap */ private boolean bitmapPoolDisabled; /** * 纠正图片方向,可让被旋转了的图片以正常方向显示 */ private boolean correctImageOrientation; public LoadOptions() { reset(); } @SuppressWarnings("unused") public LoadOptions(LoadOptions from) { copy(from); } @Override public LoadOptions setCacheInDiskDisabled(boolean cacheInDiskDisabled) { return (LoadOptions) super.setCacheInDiskDisabled(cacheInDiskDisabled); } @Override public LoadOptions setRequestLevel(RequestLevel requestLevel) { return (LoadOptions) super.setRequestLevel(requestLevel); } @Override LoadOptions setRequestLevelFrom(RequestLevelFrom requestLevelFrom) { return (LoadOptions) super.setRequestLevelFrom(requestLevelFrom); } /** * 获取最大尺寸,用于计算inSampleSize,缩小图片 * * @return MaxSize */ public MaxSize getMaxSize() { return maxSize; } /** * 设置最大尺寸,用于计算inSampleSize,缩小图片 * * @param maxSize MaxSize * @return LoadOptions */ public LoadOptions setMaxSize(MaxSize maxSize) { this.maxSize = maxSize; return this; } /** * 设置最大尺寸,用于计算inSampleSize,缩小图片 * * @param width 最大宽 * @param height 最大高 * @return LoadOptions */ public LoadOptions setMaxSize(int width, int height) { this.maxSize = new MaxSize(width, height); return this; } /** * 获取修正尺寸,用于修改图片尺寸 * * @return Resize */ public Resize getResize() { return resize; } /** * 设置修正尺寸,用于修改图片尺寸 * * @param resize Resize * @return LoadOptions */ public LoadOptions setResize(Resize resize) { this.resize = resize; return this; } /** * 设置修正尺寸,用与修改图片尺寸 * * @param width 修正宽 * @param height 修正高 * @return LoadOptions */ public LoadOptions setResize(int width, int height) { this.resize = new Resize(width, height); return this; } /** * 强制使最终图片的尺寸跟resize一样 */ public boolean isForceUseResize() { return forceUseResize; } /** * 设置强制使最终图片的尺寸跟resize一样 * * @param forceUseResize 强制使最终图片的尺寸跟resize一样 * @return LoadOptions */ public LoadOptions setForceUseResize(boolean forceUseResize) { this.forceUseResize = forceUseResize; return this; } /** * 获取图片处理器 * * @return ImageProcessor */ public ImageProcessor getImageProcessor() { return imageProcessor; } /** * 设置图片处理器 * * @param processor ImageProcessor * @return LoadOptions */ public LoadOptions setImageProcessor(ImageProcessor processor) { this.imageProcessor = processor; return this; } /** * 解码GIF图片,默认只解码GIF图片的第一帧,当需要播放GIF的时候,设置解码GIF图片即可 */ public boolean isDecodeGifImage() { return decodeGifImage; } /** * 设置解码GIF图片,默认只解码GIF图片的第一帧,当需要播放GIF的时候,设置解码GIF图片即可 * * @param decodeGifImage 解码GIF图片 * @return LoadOptions */ public LoadOptions setDecodeGifImage(boolean decodeGifImage) { this.decodeGifImage = decodeGifImage; return this; } /** * 尽量返回低质量的图片,优先级低于bitmapConfig * * @see ImageType */ public boolean isLowQualityImage() { return lowQualityImage; } /** * 设置尽量返回低质量的图片,优先级低于bitmapConfig * * @param lowQualityImage 尽量返回低质量的图片 * @return LoadOptions * @see ImageType */ public LoadOptions setLowQualityImage(boolean lowQualityImage) { this.lowQualityImage = lowQualityImage; return this; } /** * 获取bitmap config,这是你强制指定的config,优先级高于lowQualityImage * * @return Bitmap.Config */ public Bitmap.Config getBitmapConfig() { return bitmapConfig; } /** * 设置你想使用的bitmap config,优先级高于lowQualityImage * * @param bitmapConfig Bitmap.Config * @return LoadOptions */ public LoadOptions setBitmapConfig(Bitmap.Config bitmapConfig) { if (bitmapConfig == Bitmap.Config.ARGB_4444 && SketchUtils.isDisabledARGB4444()) { bitmapConfig = Bitmap.Config.ARGB_8888; } this.bitmapConfig = bitmapConfig; return this; } /** * 解码时优先考虑质量还是速度 * * @return true:质量;false:速度 */ public boolean isInPreferQualityOverSpeed() { return inPreferQualityOverSpeed; } /** * 设置解码时优先考虑质量还是速度 * * @param inPreferQualityOverSpeed true:质量;false:速度 * @return LoadOptions */ public LoadOptions setInPreferQualityOverSpeed(boolean inPreferQualityOverSpeed) { this.inPreferQualityOverSpeed = inPreferQualityOverSpeed; return this; } /** * 使用缩略图模式,可以帮助生成较清晰的缩略图 */ public boolean isThumbnailMode() { return thumbnailMode; } /** * 设置使用缩略图模式,可以帮助生成较清晰的缩略图 * * @param thumbnailMode 缩略图模式 * @return LoadOptions */ public LoadOptions setThumbnailMode(boolean thumbnailMode) { this.thumbnailMode = thumbnailMode; return this; } /** * 将经过ImageProcessor、resize或thumbnailMode处理过的图片保存到磁盘缓存中,下次就直接读取,加快显示速度 */ public boolean isCacheProcessedImageInDisk() { return cacheProcessedImageInDisk; } /** * 设置将经过ImageProcessor、resize或thumbnailMode处理过的图片保存到磁盘缓存中,下次就直接读取,加快显示速度 * * @param cacheProcessedImageInDisk true:缓存 * @return LoadOptions */ public LoadOptions setCacheProcessedImageInDisk(boolean cacheProcessedImageInDisk) { this.cacheProcessedImageInDisk = cacheProcessedImageInDisk; return this; } /** * 禁止从bitmap pool从寻找可复用的bitmap */ public boolean isBitmapPoolDisabled() { return bitmapPoolDisabled; } /** * 设置禁止从bitmap pool从寻找可复用的bitmap * * @param bitmapPoolDisabled 禁止从bitmap pool从寻找可复用的bitmap * @return LoadOptions */ public LoadOptions setBitmapPoolDisabled(boolean bitmapPoolDisabled) { this.bitmapPoolDisabled = bitmapPoolDisabled; return this; } /** * 是否纠正图片的方向,让被旋转了的图片以正常方向显示 */ public boolean isCorrectImageOrientation() { return correctImageOrientation; } /** * 设置纠正图片的方向,让被旋转了的图片以正常方向显示 * * @param correctImageOrientation true:纠正图片的方向,让被旋转了的图片以正常方向显示 * @return LoadOptions */ public LoadOptions setCorrectImageOrientation(boolean correctImageOrientation) { this.correctImageOrientation = correctImageOrientation; return this; } @Override public void reset() { super.reset(); maxSize = null; resize = null; lowQualityImage = false; imageProcessor = null; decodeGifImage = false; forceUseResize = false; bitmapConfig = null; inPreferQualityOverSpeed = false; thumbnailMode = false; cacheProcessedImageInDisk = false; bitmapPoolDisabled = false; correctImageOrientation = false; } /** * 拷贝属性,绝对的覆盖 * * @param options 来源 */ public void copy(LoadOptions options) { if (options == null) { return; } //noinspection RedundantCast super.copy((DownloadOptions) options); maxSize = options.maxSize; resize = options.resize; lowQualityImage = options.lowQualityImage; imageProcessor = options.imageProcessor; decodeGifImage = options.decodeGifImage; forceUseResize = options.forceUseResize; bitmapConfig = options.bitmapConfig; inPreferQualityOverSpeed = options.inPreferQualityOverSpeed; thumbnailMode = options.thumbnailMode; cacheProcessedImageInDisk = options.cacheProcessedImageInDisk; bitmapPoolDisabled = options.bitmapPoolDisabled; correctImageOrientation = options.correctImageOrientation; } /** * 合并指定的LoadOptions,合并的过程并不是绝对的覆盖,专门为{@link LoadHelper#options(LoadOptions)}方法提供 * <br>简单来说自己已经设置了的属性不会被覆盖,对于都设置了但可以比较大小的,较小的优先 */ public void merge(LoadOptions options) { if (options == null) { return; } //noinspection RedundantCast super.merge((DownloadOptions) options); if (maxSize == null) { maxSize = options.getMaxSize(); } else if (options.getMaxSize() != null) { // 当两者都有值时谁的像素数少用谁 int optionMaxSizePixelCount = options.getMaxSize().getWidth() * options.getMaxSize().getHeight(); int oldMaxSizePixelCount = maxSize.getWidth() * maxSize.getHeight(); if (optionMaxSizePixelCount < oldMaxSizePixelCount) { maxSize = options.getMaxSize(); } } if (resize == null) { resize = options.resize; } if (!forceUseResize) { forceUseResize = options.forceUseResize; } if (!lowQualityImage) { lowQualityImage = options.lowQualityImage; } if (imageProcessor == null) { imageProcessor = options.imageProcessor; } if (!decodeGifImage) { decodeGifImage = options.decodeGifImage; } if (bitmapConfig == null) { bitmapConfig = options.bitmapConfig; } if (!inPreferQualityOverSpeed) { inPreferQualityOverSpeed = options.inPreferQualityOverSpeed; } if (!thumbnailMode) { thumbnailMode = options.thumbnailMode; } if (!cacheProcessedImageInDisk) { cacheProcessedImageInDisk = options.cacheProcessedImageInDisk; } if (!bitmapPoolDisabled) { bitmapPoolDisabled = options.bitmapPoolDisabled; } if (!correctImageOrientation) { correctImageOrientation = options.correctImageOrientation; } } @Override public StringBuilder makeKey(StringBuilder builder) { super.makeKey(builder); if (maxSize != null) { builder.append("_").append(maxSize.getKey()); } if (resize != null) { builder.append("_").append(resize.getKey()); if (forceUseResize) { builder.append("_").append("forceUseResize"); } if (thumbnailMode) { builder.append("_").append("thumbnailMode"); } } if (correctImageOrientation) { builder.append("_").append("correctImageOrientation"); } if (lowQualityImage) { builder.append("_").append("lowQualityImage"); } if (inPreferQualityOverSpeed) { builder.append("_").append("preferQuality"); } if (decodeGifImage) { builder.append("_").append("decodeGifImage"); } if (bitmapConfig != null) { builder.append("_").append(bitmapConfig.name()); } if (imageProcessor != null) { // 旋转图片处理器在旋转0度或360度时不用旋转处理,因此也不会返回key,因此这里过滤一下 String processorKey = imageProcessor.getKey(); if (!TextUtils.isEmpty(processorKey)) { builder.append("_").append(processorKey); } } return builder; } @Override public StringBuilder makeStateImageKey(StringBuilder builder) { super.makeKey(builder); if (resize != null) { builder.append("_").append(resize.getKey()); if (forceUseResize) { builder.append("_").append("forceUseResize"); } } if (lowQualityImage) { builder.append("_").append("lowQualityImage"); } if (imageProcessor != null) { // 旋转图片处理器在旋转0度或360度时不用旋转处理,因此也不会返回key,因此这里过滤一下 String processorKey = imageProcessor.getKey(); if (!TextUtils.isEmpty(processorKey)) { builder.append("_").append(processorKey); } } return builder; } }