From design to implementation, we will teach you how to implement Android-Universal-ImageLoader-decoding and display step by step, androidimageloader

Source: Internet
Author: User

From design to implementation, we will teach you how to implement Android-Universal-ImageLoader-decoding and display step by step, androidimageloader

Indicate the source for reprinting. This article is from the blog of chaossss.

Android-Universal-ImageLoader Github address

In the previous blog article, I analyzed the design and implementation of the cache function in Android-Universal-ImageLoader. I hope you can learn something to lose. Today, I will go on to introduce the image decoding and display functions in the AUI core category. If you have not read the previous blog, you can stamp it into the Forum, enter the subject below:

Image decoding

Before considering the specific implementation, let's first think about the role of a decoder? I believe everyone can blurt out the answer: decoding. The core function of the Decoder is decoding. In other words, when designing the Decoder class, we should follow the single responsibility principle:

public interface ImageDecoder {    Bitmap decode(ImageDecodingInfo imageDecodingInfo) throws IOException;}

What do you do when you see the ImageDecodingInfo parameter in the decode () method? We only need to decode the image. Don't worry. Let's first simulate the entire image decoding process in our mind:

To decode an image, we need to obtain the "Source" of the image. The image may come from the Network (then we have to call the download module to download the image ), the image may come from a local file (so we have to read it through the IO stream ). After obtaining the image source, we are about to start decoding. We certainly have not only one solution, but sometimes it may be displayed, sometimes the image needs to be displayed in high definition without losing sight, or we need to scale/zoom in the image, or even customize the length and width of the image, this means that we need a decoding helper class to store the information required for decoding, so that the decoding operation can be completed.

So now we should be able to understand the role of ImageDecodingInfo, right? Let's take a look at its source code:

Public class ImageDecodingInfo {private final String imageKey; private final String imageUri; private final String originalImageUri; private final ImageSize targetSize; private final ImageScaleType imageScaleType; private final ViewScaleType viewScaleType; private final ImageDownloader downloader; private final Object extraForDownloader; private final boolean considerExifParams; private final Opti Ons decodingOptions; public ImageDecodingInfo (String imageKey, String imageUri, String originalImageUri, ImageSize targetSize, ViewScaleType viewScaleType, ImageDownloader downloader, DisplayImageOptions displayOptions) {this. imageKey = imageKey; this. imageUri = imageUri; this. originalImageUri = originalImageUri; this.tar getSize = targetSize; this. imageScaleType = displayOptions. getImageScaleType (); This. viewScaleType = viewScaleType; this. downloader = downloader; this. extraForDownloader = displayOptions. getExtraForDownloader (); considerExifParams = displayOptions. isConsiderExifParams (); decodingOptions = new Options (); copyOptions (displayOptions. getDecodingOptions (), decodingOptions);} private void copyOptions (Options srcOptions, Options destOptions) {destOptions. inDensity = srcOptions. InDensity; destOptions. inDither = srcOptions. inDither; destOptions. ininputexcepable = srcOptions. ininputretriable; destOptions. inJustDecodeBounds = srcOptions. inJustDecodeBounds; destOptions. inPreferredConfig = srcOptions. inPreferredConfig; destOptions. inPurgeable = srcOptions. inPurgeable; destOptions. inSampleSize = srcOptions. inSampleSize; destOptions. inScaled = srcOptions. inScaled; destOptions. InScreenDensity = srcOptions. inScreenDensity; destOptions. inTargetDensity = srcOptions. inTargetDensity; destOptions. inTempStorage = srcOptions. inTempStorage; if (Build. VERSION. SDK_INT> = 10) copyOptions10 (srcOptions, destOptions); if (Build. VERSION. SDK_INT> = 11) copyOptions11 (srcOptions, destOptions);} // get method omitted ............ @ TargetApi (10) private void copyOptions10 (Options srcOptions, Options destOptions) {destOptions. inPreferQualityOverSpeed = srcOptions. inPreferQualityOverSpeed;} @ TargetApi (11) private void copyOptions11 (Options srcOptions, Options destOptions) {destOptions. inBitmap = srcOptions. inBitmap; destOptions. inMutable = srcOptions. inMutable ;}}
BaseImageDecoder

After obtaining the base class ImageDecoder of the image decoder, We have to complete our specific implementation. Now we have to think about the Implementation Details of ImageDecoder Based on the Abstract: decode () method of ImageDecoder. To complete image decoding, follow these steps:

Obtain the image's "Source"-> obtain the image input stream and determine the actual size of the image, whether it needs to be cut, and whether it needs to be rotated-> obtain the image-> process the Image Based on the Image Information and decoding settings -> get images that meet the requirements

Since the implementation idea has been finalized, it is certainly not difficult to implement it:

    @Override    public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {        Bitmap decodedBitmap;        ImageFileInfo imageInfo;        InputStream imageStream = getImageStream(decodingInfo);        if (imageStream == null) {            L.e(ERROR_NO_IMAGE_STREAM, decodingInfo.getImageKey());            return null;        }        try {            imageInfo = defineImageSizeAndRotation(imageStream, decodingInfo);            imageStream = resetStream(imageStream, decodingInfo);            Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);            decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);        } finally {            IoUtils.closeSilently(imageStream);        }        if (decodedBitmap == null) {            L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());        } else {            decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, decodingInfo, imageInfo.exif.rotation,                    imageInfo.exif.flipHorizontal);        }        return decodedBitmap;    }

I will not release all the code. You can follow the implementation here to enter the corresponding method. The ExifInfo and ImageFileInfo classes are only auxiliary classes required for decoding. They provide some information required for image processing, such as the size of the image file, whether the image needs to be cut, or rotated:

protected static class ExifInfo {    public final int rotation;    public final boolean flipHorizontal;    protected ExifInfo() {        this.rotation = 0;        this.flipHorizontal = false;    }    protected ExifInfo(int rotation, boolean flipHorizontal) {        this.rotation = rotation;        this.flipHorizontal = flipHorizontal;    }}protected static class ImageFileInfo {    public final ImageSize imageSize;    public final ExifInfo exif;    protected ImageFileInfo(ImageSize imageSize, ExifInfo exif) {        this.imageSize = imageSize;        this.exif = exif;    }}
Image Display

In fact, we will find that the two functions of Image Display and image decoding are very similar in implementation: single abstraction (Image Display/image decoding ), you only need to abstract the implementation details based on the corresponding requirements.

public interface BitmapDisplayer {    void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom);}

When we display an image, we may need to display a circular, rectangular, or rounded image, or set an animation for the image ...... In fact, we only need to set/implement the corresponding Drawable and Animation based on the corresponding image shape and Animation. I don't think there is anything to say here ...... However, an ImageAware interface is introduced here, which deserves our attention:

public interface ImageAware {    int getWidth();    int getHeight();    ViewScaleType getScaleType();    View getWrappedView();    boolean isCollected();    int getId();    boolean setImageDrawable(Drawable drawable);    boolean setImageBitmap(Bitmap bitmap);}

Through this interface, you can obtain the View information of the displayed image in the image display class. You can also modify the image, image shape, and image ID. Some may say that, however, there is no such thing ...... But do you think about it? Without this interface, how can we directly Display the image as a circle in the Display class, or add the corresponding animation? You must know that the final implementation of these effects is applied to the View.

Of course, displaying circular images and animations can certainly be achieved, such as custom views, or passing a View as a parameter to Display, in the Display class, process the View of each Display image or obtain the View attributes. The practices in AUI are also worth reference, because they strip the logic and avoid coupling.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.