From design to implementation, we will teach you how to implement the Android-Universal-ImageLoader-tool class and androidimageloader step by step.
Indicate the source for reprinting. This article is from:Chaossss blog
In the previous blog, we analyzed the function implementation and Architecture Design of The AUImgLoader cache module. Today, we may wish to analyze the tool class of AUImgLoader to pave the way for subsequent analysis.
In the Utils package, there are tools that AUImgLoader may use. DiskCacheUtils, StorageUtils, and MemonryCacheUtils are described in the analysis of the AUImgLoader cache function module. In fact, the classes implemented as tools in AUImgLoader are not only classes in Utils packages, such as FileNameGenerator and download ...... If you don't talk nonsense, go to the topic:
ImageSizeUtils
Provides calculations with image sizes, scales
The ImageSizeUtils class only contains more than 200 lines of code. The main function is to calculate the image length and image proportion. in the class, the main function is to process the ImageSize object. What is the ImageSize object?
ImageSize
public class ImageSize { private static final int TO_STRING_MAX_LENGHT = 9; 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; } public ImageSize scaleDown(int sampleSize) { return new ImageSize(width / sampleSize, height / sampleSize); } 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(); }}
SEPARATORIs a delimiter used to separate the length and width of an image.
TO_STRING_MAX_LENGHTIndicates the maximum length of a string of the image size, for example, 9999x9999.
The ImageSize constructor requires us to pass in the height and width, scaleDown () and scale () methods to process the image length and width to narrow/enlarge the image size. In general, ImageSize is a simple class that represents the image size.
Static Methods in ImageSizeUtils
Now that we know what ImageSize is, let's continue the analysis of ImageSizeUtils:
The following code is executed when you obtain the ImageSizeUtils singleton:
static { 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); }
This code is mainly used to ensure that the image size does not exceed the defined maximum size, that is, 2048x2048.
DefineTargetSizeForView ()
In the defineTargetSizeForView () method, if the wid and height of ImageAware are greater than 0, the ImageSize object with the length and width of ImageAware as the image size is returned. If the value is smaller than 0, returns the ImageSize object constructed by the long width value stored in the maxImageSize object.
public static ImageSize defineTargetSizeForView(ImageAware imageAware, ImageSize maxImageSize) { 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); }
ImageAware
What is the ImageAware object?
public interface ImageAware { int getWidth(); int getHeight(); ViewScaleType getScaleType(); View getWrappedView(); boolean isCollected(); int getId(); boolean setImageDrawable(Drawable drawable); boolean setImageBitmap(Bitmap bitmap);}
As we can see, ImageAware is an interface. From the definition of it, we can know that in the process of using ImageLoader, ImageAware provides all the attributes required for image processing/display. In addition, through its callback method, we can obtain all views for obtaining images through ImageLoader and then displaying images.
ComputeImageSampleSize () method
The computeImageSampleSize () method looks a little long. We can see it:
computeImageSampleSize(ImageSize srcSize, ImageSize targetSize, ViewScaleType viewScaleType, boolean powerOf2Scale)
First, the four parameters of this method represent:
- SrcSize-initial (image) Size
- TargetSize-target (View Size of the image)
- ViewScaleType-Display Mode of the image in View (scaling/partial display, etc ......)
- PowerOf2Scale-whether the image size is a multiple of 2
Inside the method, we first obtain the length and width of the initial size and the target size, and then initialize the variable scale indicating the image proportion to 1, and enter a switch selection statement to process the scale variable:
switch (viewScaleType) { case FIT_INSIDE: …… break; case CROP: …… break;}
The FIT_INSIDE and CROP values appear in the selection statement. We have never seen these two values. What is it ...... Ctrl + Click in. We found that both of them are ViewScaleType enumerated values:
public enum ViewScaleType { FIT_INSIDE, CROP;}
From the notes, when using FIT_INSIDE, the length and width of the image must be at least one value smaller than or equal to the length or width of the View, to ensure that the image can be fully displayed in the View (but may be scaled). When CROP is used, the length and width of the image are greater than or equal to the length and width of the View, the image may be incomplete because it will be dropped.
To understand the use of these two values, we can continue to analyze the following:
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;}
Because the processing in the two judgment blocks is very similar, I will only analyze the situation in FIT_INSIDE:
First, check the value of powerOf2Scale. If the value of powerOf2Scale is false, it indicates that the image size is not a multiple of 2. Then, divide the initial value by the target value and the result with the smallest proportion is the scale value.
If powerOf2Scale is true, it indicates that the image size is a multiple of 2. First, we need to get 1/2 of the initial size, and then multiply the scale value by 2 through the loop, so that we can continue to divide halfwidth and halfHeight, until either of them is larger than the target size and the cycle ends, the scale value is the final value.
Because the image display must be full of the entire View, after processing the scale by selecting a statement, you need to check the scale value. If it is smaller than 1, you need to set the scale value to 1. Then run the considerMaxTextureSize () method.
ConsiderMaxTextureSize () method
After the computeImageSampleSize () method is executed, the processed scale value is obtained. At the end of the method, we need to use the considerMaxTextureSize () method to process the scale value. Then, considerMaxTextureSize () what did the method do?
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; }
In the past, we used the initial size and the calculated scale value to determine whether the scaled length/width exceeds the maximum image size we have defined. If it exceeds, you need to increase the scale value to increase the scale ratio.
The computeMinImageSampleSize () method is simple and does not analyze and pull data.
The computeImageScale () method is opposite to the computeImageSampleSize () method, and calculates the scale ratio of the initial size from the target size.
IoUtils, L
In fact, the methods in IoUtils and L classes are simple. They encapsulate some common operations to simplify the actual amount of code.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.