Image processing for Android Development (II): Asynchronous loading and compression of images using Asynctask and callback interfaces

Source: Internet
Author: User

On the topic of image processing for Android development (i): Building a picture cache with soft references we talked about how to build a cache using soft-referencing technology. So if you want to use a picture, you have to have the source of the picture first. Generally, an app's picture resources are obtained from the server. Today, we use the Android Development Network Request Communication Special topic (II): httpclient-based file upload download inside the encapsulated httputils to achieve the download of the picture, and then loaded into the local with the soft reference cache use, a ListView as an example to illustrate.


First, the preparatory workWe need to prepare the following classes (Picture object and soft reference cache class please refer to the previous topic):
1, Picture download class ImageDownload2, image Download Tool Freedomhttpclientutil (reference: Android Development Network Request Communication Special topic (b): httpclient-based file upload download) 3, Image download Asynchronous Processing Task LoadTask4, callback interface Freedomcallback

Second, the preparation of the tool class1. Preparation of Callback interface
Public interface Freedomcallback {/** * @Title: imageloaded * @Description: TODO * @param imagedrawable returned Bitmap object * @par Am tag is used for ListView lookup control * @throws */public void imageloaded (Bitmap imagedrawable, Object tag);}

2. Picture Download class and asynchronous Processing taskImage download Asynchronous Processing task we made it into the inner class of the image download class.
public class Imagedownload {private static final string TAG = "Imagedownload";p rivate static string path;//build cache address static {I F (Environment.getexternalstoragestate (). Equals (environment.media_mounted)) {File externalstoragedirectory = Environment.getexternalstoragedirectory ();p ath = externalstoragedirectory.getabsolutepath () + ConstantValue.IMAGE_ PATH; File directory = new file (path), if (!directory.exists ()) {directory.mkdirs ();}} else {path = null; LOG.E (TAG, "no sdcard.");}} /** * @Title: loaddrawable * @Description: Download image * @param imageUrl * @param simplename * @param imagecallback * @throws */p ublic void Loaddrawable (String imageUrl, String Simplename,freedomcallback imagecallback) {New Freedomloadtask ( Imagecallback). Execute (IMAGEURL, simplename);} /** * @Title: Loadimagefromurl * @Description: Download image according to address * @param URL * @return * @throws */public Bitmap Loadimagefromurl ( String URL) {InputStream i = null;try {freedomhttpclientutil util = new Freedomhttpclientutil (); Util.open (URL, freedomhtt PcliEntutil.get); Util.post (); i = Util.openinputstream ();//Get stream and create Bitmapbitmap bitmap = Bitmapfactory.decodestream (i); return bitmap;} catch (Exception e) {e.printstacktrace ();} return null;} /** * @Title: Saveimage2sdcard * @Description: Store the picture on the SD card * @param simplename * @param bitmap * @throws */public void Save Image2sdcard (String simplename, Bitmap Bitmap) {if (Stringutils.isnotblank (path)) {File File = new file (path), si Mplename + ". png"); FileOutputStream FOut = null;try {fOut = new FileOutputStream (file),//bitmap is written to the stream bitmap.compress ( Bitmap.CompressFormat.PNG, FOut); Fout.flush ();} catch (Exception e) {org.cao.optimization.util.Log.info ("file cannot be created"); E.printstacktrace ();} finally {if (fOut! = null) try { Fout.close ();} catch (IOException e) {e.printstacktrace ();}}}} /** * @ClassName: Freedomloadtask * @author victor_freedom ([email protected]) * @createddate 2015-1-31 11:39:18 * @Description: Image download, return a Bitmap object */class Freedomloadtask extends Asynctask<string, Integer, bitmap&Gt {Private Freedomcallback imagecallback;public freedomloadtask (freedomcallback imagecallback) {this.imageCallback = Imagecallback;} @Overrideprotected Bitmap doinbackground (String ... params) {//pass in two parameters, one is the download path, one is the file name Bitmap Bitmap = Loadimagefromurl ( Params[0]); if (bitmap! = null) {//Save to SD card Saveimage2sdcard (params[1], bitmap);//Join Cache Imagecache.getinstance (). Cacheimage (New Image (Params[1], bitmap));} return bitmap;} @Overrideprotected void OnPostExecute (Bitmap result) {//After a successful download executes the callback interface imagecallback.imageloaded (result, NULL); Super.onpostexecute (result);}}}

Three, interface processing 1, adapter place GetView TreatmentWe assume that Adater has only one imageview, using the Viewholder cache, so in the GetView method, we handle this:
Get the name of the picture final String id = infos.getname ();//give here ImageView space settings idcontiner.image.setTag (ID);// According to the first name from the soft application to get bitmapimage image = Imagecache.getinstance (). GetImage (ID); Bitmap Bitmap = Image.getbitmap ();//Determine if Bitmap is empty if (Bitmap = = null) {//Determine if there is a relevant file in local SDcard if (Image.hasfile (ID)) { InputStream Is;try {is = new FileInputStream (Image.getfilefromsdcard (ID)), bitmap = Bitmapfactory.decodestream (IS); Magecache.getinstance (). Cacheimage (new Image (ID, bitmap)); Continer.image.setImageBitmap (bitmap);} catch (FileNotFoundException e) {e.printstacktrace ();}} else {//not locally, download imagedownload download = new Imagedownload () from the server;d ownload.loaddrawable (News.getimgurl (), id + "", New Freedomcallback () {@Overridepublic void imageloaded (Bitmap imagedrawable,object tag) {if (imagedrawable! = null) {// The callback interface passed in when building adapter, if the download picture succeeds, callback this method listcallback.imageloaded (imagedrawable, id);}}); Continer.image.setImageResource (R.drawable.ic_launcher);}} else {//If the soft reference is still present, take it directly with Continer.image.setImageBitmap (bitmap);}

2. ListView initialization related processing

adapter = new Newsadapter (context, new Listcallback () {@Overridepublic void imageloaded (Bitmap Bitmap, Object tag) {//Based on callback Returns the tag to find the corresponding Imageviewimageview ImageView = (imageView) listview.findviewwithtag (tag); if (ImageView! = null) { Imageview.setimagebitmap (bitmap);}}); ListView = new ListView (context); Listview.setadapter (adapter);

Four, image compressionIn the above process, we can also optimize the next. During the above operation, we default the size of the downloaded image is already set. Of course, in the actual development, we download the pictures, may also be good communication with the server to set up. However, sometimes, pictures are downloaded very large, this time, you need to compress the image. In general, there are two compression of images, quality compression and wide-height compression. Let's look at a tool class. This is the blogger didn't know where to find from before.
Picture quality compression public static Bitmap Compressimage (Bitmap image) {Bytearrayoutputstream BAOs = new Bytearrayoutputstream (); Image.compress (Bitmap.CompressFormat.JPEG, BAOs);//Quality compression method, here 100 means no compression, the compressed data stored in the BAOs int options = 100;while ( Baos.tobytearray (). length/1024 > 100) {//cycle to determine if the image is larger than 100kb after compression, greater than the continuation of compression baos.reset ();//reset BAOs to Empty baosimage.compress (Bitmap.CompressFormat.JPEG, Options, BAOs);//compress options% here, store compressed data into BAOs options-= 10;//reduce each time by 10} Bytearrayinputstream ISBM = new Bytearrayinputstream (Baos.tobytearray ());// The compressed data BAOs stored in the bytearrayinputstream bitmap bitmap = Bitmapfactory.decodestream (ISBM, NULL, NULL);// Generate a picture of the Bytearrayinputstream data return bitmap;} Picture width high compression public static Bitmap getimage (String srcpath) {bitmapfactory.options newopts = new Bitmapfactory.options ();// Start to read the picture, at this time set the Options.injustdecodebounds back to true newopts.injustdecodebounds = true; Bitmap Bitmap = Bitmapfactory.decodefile (Srcpath, newopts);//return BM At this time is empty newopts.injustdecodebounds = false;int W = newopts . outwidth;int h = newopts.outheight;//This setting the width of the picture, according to the actual need to set float HH = 800f;//Here Set the height for 800ffloat ww = 480f;//here to set the width to 480f//zoom ratio. Because it is a fixed scale, only one of the data of high or wide can be calculated by the int be = 1;//be=1 means not to scale if (W > H && w > ww) {//If the width is large then scale be = (int) According to the fixed width size OPTS.OUTWIDTH/WW);} else if (W < h && h > hh) {//If height is high, scale is = (int) (NEWOPTS.OUTHEIGHT/HH) According to the fixed width size;} if (be <= 0) is = 1;newopts.insamplesize = be;//Set scaling//Reread the picture, note that the options.injustdecodebounds has been set back to false bitmap = Bitm Apfactory.decodefile (Srcpath, newopts); return Compressimage (bitmap);//compress good proportions and then mass compress}

Sometimes, we can also let the system automatically compression to us, as long as to ensure that there is no oom error and can let the picture with maximum performance to show

File File = Image.getfilefromsdcard (name, "pure"), Options opts = new options (); opts.injustdecodebounds = true; Bitmapfactory.decodefile (File.getabsolutepath (), opts); opts.injustdecodebounds = false;//automatically compresses the system according to the set value, This line of code is the first parameter is bitmapfactory.options, the second parameter is adjusted after the picture is the smallest width or height, the third parameter is the adjusted image of the upper limit of memory consumption. Opts.insamplesize = Util.computesamplesize (opts, n, (int) (1 * 1024x768 * 1024x768)); opts.indither = False;<span style= "White -space:pre "></span>opts.inpreferredconfig = Bitmap.config.argb_8888;bitmap = BitmapFactory.decodeFile ( File.getabsolutepath (), opts);

Picture compression steps are generally set after the picture is downloaded.

At this point, the pictures from the download to the display of all the process, we have implemented. Of course, this is just a way of implementation, the image of the asynchronous loading can also have other implementation methods. Today we review the Web request communication topic for Android Development (ii): httpclient-based file upload download content in the encapsulated Httputils, the next we use the thread pool previously learned threadpoolexcutor mates Web request communication for Android development (i): asynchronous loading of a large number of images of a ListView, based on the httpurlconection described in the HttpURLConnection request communication.

Image processing for Android Development (II): Asynchronous loading and compression of images using Asynctask and callback interfaces

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.