Universal-Image-Loader源码阅读(4)-utilsImageSizeUtils

    xiaoxiao2025-08-07  6

    该工具类继承了L,IoUtils的特点。不过要相对代码量大了一点了。

    该工具类是用于计算图片大小的,以及计算两个尺寸之间的缩放比例的。

    源码:

    /** * Provides calculations with image sizes, scales * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.8.3 */ public final class ImageSizeUtils { private static final int DEFAULT_MAX_BITMAP_DIMENSION = 2048;//默认的图片最大尺寸 private static ImageSize maxBitmapSize;//ImageSize其实就是width*height static {//实地计算maxBitmapSize int[] maxTextureSize = new int[1]; GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);//需要根据实际情况来定 int maxBitmapDimension = Math.max(maxTextureSize[0], DEFAULT_MAX_BITMAP_DIMENSION); maxBitmapSize = new ImageSize(maxBitmapDimension, maxBitmapDimension); } private ImageSizeUtils() { } /** * Defines target size for image aware view. Size is defined by target * {@link com.nostra13.universalimageloader.core.imageaware.ImageAware view} parameters, configuration * parameters or device display dimensions.<br /> */ public static ImageSize defineTargetSizeForView(ImageAware imageAware, ImageSize maxImageSize) {//imageAware相当于显示图片的控件,maxImageSize表示设定的最大显示大小,通过这两个参数,计算出一个我们需要的大小,优先选择imageAware的尺寸,因为它是用来显示图片,他多大,图片就显示多大 int width = imageAware.getWidth(); if (width <= 0) width = maxImageSize.getWidth(); int height = imageAware.getHeight(); if (height <= 0) height = maxImageSize.getHeight(); return new ImageSize(width, height); } /** * Computes sample size for downscaling image size (<b>srcSize</b>) to view size (<b>targetSize</b>). This sample * size is used during * {@linkplain BitmapFactory#decodeStream(java.io.InputStream, android.graphics.Rect, android.graphics.BitmapFactory.Options) * decoding image} to bitmap.<br /> * <br /> * <b>Examples:</b><br /> * <p/> * <pre> * srcSize(100x100), targetSize(10x10), powerOf2Scale = true -> sampleSize = 8 * srcSize(100x100), targetSize(10x10), powerOf2Scale = false -> sampleSize = 10 * * srcSize(100x100), targetSize(20x40), viewScaleType = FIT_INSIDE -> sampleSize = 5 * srcSize(100x100), targetSize(20x40), viewScaleType = CROP -> sampleSize = 2 * </pre> * <p/> * <br /> * The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded * bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 * the number of pixels. Any value <= 1 is treated the same as 1. * * @param srcSize Original (image) size//原始图片的小 * @param targetSize Target (view) size//目标图片大小 * @param viewScaleType {@linkplain ViewScaleType Scale type} for placing image in view//图片缩放类型 * @param powerOf2Scale <i>true</i> - if sample size be a power of 2 (1, 2, 4, 8, ...)//取样比例是否需要是2的倍数 * @return Computed sample size//最终获得的取样比例。依据此取样比例获取到的图片大小不一定等于目标图片大小 */ public static int computeImageSampleSize(ImageSize srcSize, ImageSize targetSize, ViewScaleType viewScaleType, boolean powerOf2Scale) {//计算缩放图片时的缩放比例(取样比例) final int srcWidth = srcSize.getWidth(); final int srcHeight = srcSize.getHeight(); final int targetWidth = targetSize.getWidth(); final int targetHeight = targetSize.getHeight(); int scale = 1; switch (viewScaleType) { case FIT_INSIDE: if (powerOf2Scale) { final int halfWidth = srcWidth / 2; final int halfHeight = srcHeight / 2; while ((halfWidth / scale) > targetWidth || (halfHeight / scale) > targetHeight) { // || scale *= 2; } } else { scale = Math.max(srcWidth / targetWidth, srcHeight / targetHeight); // max } break; case CROP: if (powerOf2Scale) { final int halfWidth = srcWidth / 2; final int halfHeight = srcHeight / 2; while ((halfWidth / scale) > targetWidth && (halfHeight / scale) > targetHeight) { // && scale *= 2; } } else { scale = Math.min(srcWidth / targetWidth, srcHeight / targetHeight); // min } break; } if (scale < 1) { scale = 1; } scale = considerMaxTextureSize(srcWidth, srcHeight, scale, powerOf2Scale);//缩放后不能大于maxBitmapSize,再次修订scale return scale; } private static int considerMaxTextureSize(int srcWidth, int srcHeight, int scale, boolean powerOf2) { final int maxWidth = maxBitmapSize.getWidth(); final int maxHeight = maxBitmapSize.getHeight(); while ((srcWidth / scale) > maxWidth || (srcHeight / scale) > maxHeight) { if (powerOf2) { scale *= 2; } else { scale++; } } return scale; } /** * Computes minimal sample size for downscaling image so result image size won't exceed max acceptable OpenGL * texture size.<br /> * We can't create Bitmap in memory with size exceed max texture size (usually this is 2048x2048) so this method * calculate minimal sample size which should be applied to image to fit into these limits. * * @param srcSize Original image size * @return Minimal sample size */ public static int computeMinImageSampleSize(ImageSize srcSize) {//计算最小的取样比率,maxBitmapSize作为目的大小 final int srcWidth = srcSize.getWidth(); final int srcHeight = srcSize.getHeight(); final int targetWidth = maxBitmapSize.getWidth(); final int targetHeight = maxBitmapSize.getHeight(); final int widthScale = (int) Math.ceil((float) srcWidth / targetWidth); final int heightScale = (int) Math.ceil((float) srcHeight / targetHeight); return Math.max(widthScale, heightScale); // max } /** * Computes scale of target size (<b>targetSize</b>) to source size (<b>srcSize</b>).<br /> * <br /> * <b>Examples:</b><br /> * <p/> * <pre> * srcSize(40x40), targetSize(10x10) -> scale = 0.25 * * srcSize(10x10), targetSize(20x20), stretch = false -> scale = 1 * srcSize(10x10), targetSize(20x20), stretch = true -> scale = 2 * * srcSize(100x100), targetSize(20x40), viewScaleType = FIT_INSIDE -> scale = 0.2 * srcSize(100x100), targetSize(20x40), viewScaleType = CROP -> scale = 0.4 * </pre> * * @param srcSize Source (image) size * @param targetSize Target (view) size * @param viewScaleType {@linkplain ViewScaleType Scale type} for placing image in view * @param stretch Whether source size should be stretched if target size is larger than source size. If <b>false</b> * then result scale value can't be greater than 1. * @return Computed scale */ public static float computeImageScale(ImageSize srcSize, ImageSize targetSize, ViewScaleType viewScaleType, boolean stretch) {//计算缩放比例 final int srcWidth = srcSize.getWidth(); final int srcHeight = srcSize.getHeight(); final int targetWidth = targetSize.getWidth(); final int targetHeight = targetSize.getHeight(); final float widthScale = (float) srcWidth / targetWidth; final float heightScale = (float) srcHeight / targetHeight; final int destWidth; final int destHeight; if ((viewScaleType == ViewScaleType.FIT_INSIDE && widthScale >= heightScale) || (viewScaleType == ViewScaleType.CROP && widthScale < heightScale)) {//FIT_INSIDE:长边等于view的对应边;CROP:短边等于view的对应边 destWidth = targetWidth; destHeight = (int) (srcHeight / widthScale); } else { destWidth = (int) (srcWidth / heightScale); destHeight = targetHeight; } float scale = 1;//不允许拉伸时,scale<=1,只能缩放,目的尺寸比原始尺寸小; if ((!stretch && destWidth < srcWidth && destHeight < srcHeight) || (stretch && destWidth != srcWidth && destHeight != srcHeight)) { scale = (float) destWidth / srcWidth; }//如果不允许拉伸,而且目的尺寸比原始尺寸大,则伸缩比例为1 return scale; } }

    最简单的ImageSize结构:

    /** * Present width and height values * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.0.0 */ public class ImageSize { private static final int TO_STRING_MAX_LENGHT = 9; // "9999x9999".length() private static final String SEPARATOR = "x"; private final int width; private final int height; public ImageSize(int width, int height) { this.width = width; this.height = height; } public ImageSize(int width, int height, int rotation) { if (rotation % 180 == 0) { this.width = width; this.height = height; } else { this.width = height; this.height = width; } } public int getWidth() { return width; } public int getHeight() { return height; } /** Scales down dimensions in <b>sampleSize</b> times. Returns new object. */ public ImageSize scaleDown(int sampleSize) { return new ImageSize(width / sampleSize, height / sampleSize); } /** Scales dimensions according to incoming scale. Returns new object. */ public ImageSize scale(float scale) { return new ImageSize((int) (width * scale), (int) (height * scale)); } @Override public String toString() { return new StringBuilder(TO_STRING_MAX_LENGHT).append(width).append(SEPARATOR).append(height).toString(); } }

    转载请注明原文地址: https://ju.6miu.com/read-1301502.html
    最新回复(0)