Because reading images from a file to Bitmap is a time-consuming task, I studied several feasible methods and compared them.
First, let me explain why it takes time. This is because when reading Bitmap from jpg or png files, first, external memory needs to be operated and the image files are generally larger. Second, when creating Bitmap, you basically need to operate on the original image, such as downsampling, shearing, rotation, etc. Therefore, how to read and present pictures efficiently is a question worth studying.
Based on my idea, I came up with 3 solutions:
1. Read and manipulate the image directly in the current UI thread, and then render it.
2. Open a new child thread to read and operate the image, and then pass it back to the UI thread and render it using the relevant methods of Serializable in the Bundle.
3. Other methods are the same as 2, but they use the relevant methods of Parcelable in Bundle.
Method 1
start_time = (); options=new (); = true; Bitmap bitmap=(path,options); =calculateSize(options,width,height); =false; //The entire image, downsampling bitmap=(path,options); //Some images Bitmap patch=(bitmap, 10, 10, 100, 100); end_time = (); ("BitmapTest", "UI time consume:"+(end_time - start_time)); (bitmap); (patch);
The operation is very simple. First read out the size and other information of the image file, then calculate its scaling ratio based on its size, and cut out a part of the image. Finally, display the image on the ImageView space. After roughly measuring it dozens of times, the average consumption time obtained is: 72.75ms
Method 2
Start the child thread
start_time = (); String path=().getPath()++""; ImgThread imgThread=new ImgThread(msgHandler,path,width,height); ();
The operations in the child thread are basically the same as 1
options=new (); = true; Bitmap bitmap=(path,options); =calculateSize(options,width,height); =false; //The entire image, downsampling bitmap=(path,options); //Some images Bitmap patch=(bitmap, 10, 10, 100, 100); array=new ArrayList<Bitmap>(2); (bitmap); (patch); //Serializable delivery Bundle bundle=new Bundle(); ("img", array); //Parcelable delivery /* MyList l=new MyList(()); =array; ("img", l); */ Message msg= new Message(); =1; (bundle); (msg);
Pass Bitmap back to the UI thread and render
Bundle bundle=(); //Serializable delivery ArrayList<Bitmap> array=(ArrayList<Bitmap>) ("img"); //Parcelable delivery //MyList l=(MyList)("img"); //ArrayList<Bitmap> array=;//=(ArrayList<Bitmap>) ("img"); Bitmap bitmap=(0); Bitmap patch=(1); end_time = (); ("BitmapTest", "Th time consume:"+(end_time - start_time)); (bitmap); (patch);
The average consumption time of method two is: 83.93ms
Method 3
This method requires a new class to implement the Parcelable interface
package ; import ; import ; import ; public class MyList implements Parcelable{ public ArrayList array; public MyList(Parcel in) { (null); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { (array); } public static final <MyList> CREATOR = new <MyList>() { @Override public MyList createFromParcel(Parcel source) { return new MyList(source); } @Override public MyList[] newArray(int size) { return new MyList[size]; } }; }
Operations in child threads
//Parcelable delivery MyList l=new MyList(()); =array; ("img", l);
The average consumption time of method three is: 87.35ms
Results Analysis
The three methods were tested on Meizu MX1 model mobile phones. In theory, method three should be faster than method two, but at least according to my experimental results, when transmitting a small amount of data (the image is about a few mB or hundreds of kB), the time-consuming data transmission is not the key, and the time-consuming of the two methods is about the same. Method 1 Since data transfer between threads is not used, the time is minimal.
Therefore, I concluded the following conclusions:
1. If you have to wait until the image is loaded before the user is allowed to operate, you can directly do the image operation in the UI thread. At this time, you can add a ProgressDialog to prompt that it is loading.
2. If you need to allow users to operate while loading images, you should open a new child thread, but in the case of small amount of data, there is not much difference between Serializable and Parcelable.
3. In short, when the size and number of images are not large, it is enough to directly perform image reading and other operations on the UI thread, but it is better to open a sub-thread when it is relatively large.
The above article discusses the efficiency of Android reading images from files in detail. This is all the content I have shared with you. I hope you can give you a reference and I hope you can support me more.