Android image compression upload basic article _android

Source: Internet
Author: User

In the Android program development we often see the need to upload pictures of the scene, where there is a technical point, the image needs to compress processing, and then upload. This can reduce the flow of consumption, improve the image upload speed and so on.

On how to compress the Android, there is a lot of information on the web, but most of them are snippets of code, explaining the steps of compression, without a useful tool class library. So how do you encapsulate the compression algorithm into a utility library? What problems will be encountered, such as:

1. How many pictures are needed for compression?

2. Whether the compressed image is overwritten or saved to a different directory

3. Do you want to delete the original picture if you are saving the directory?

4. If you change the size of the compressed picture size is according to the proportion of the original image reduction or directly specify the size

5. If there is a rotation problem, need not be amended

6. For multiple image compression is concurrent or linear processing

7. Can use service to compress processing, is local (locally) or remote (remotely) way to start service

8. If you need to compress a lot of pictures, how to use the thread pool to handle

Based on the above considerations, I intend to write a series of articles to solve these problems step-by-step (Forget everyone continued attention), the service, multithreading use and compression algorithms are assembled into a project. This is not only in the practical application or as a learning material is relatively good. Eventually I will open the code and iterations involved in this series to GitHub, Welcome to star, and welcome to submit bugs.

Of course, some friends may say that the actual application of the number of uploaded pictures is not too much, consider these issues is not a bit of a worry, well, if you really think so you can ignore this series of articles.

The actual demand will be based on the original image of the width and height of the compression, directly specify the size of the relatively rare, so this series of articles is also for such ratio compression.

In short, the image compression, the main focus on two points:

1. The size of the picture to scale to achieve the purpose of compression

2. The quality of the image compression

Scale the size of the picture to achieve the purpose of compression

In view of this situation and picture rotation problem, you can refer to my Android to deal with the camera rotation problem and bring the memory footprint thinking this article.

It's just to be noted that here you need to calculate the width and height (actualoutwidth,actualoutheight) of the final output picture according to the srcratio ratio of the original picture, and finally pass Actualoutwidth, Actualoutheight to compute the sampled value samplesize.

The core code is as follows:

 Lgimagecompressor.java bitmapfactory.options Options = new Bitmapfactory.options ();
Options.injustdecodebounds = true;
Bitmapfactory.decodefile (Srcimagepath, Options);
The width-height ratio of the original picture and the desired output picture of the height of the image are computed in the final output of the picture's wide and high float srcwidth = options.outwidth;
float srcheight = options.outheight;
float maxwidth = outwidth;//expected output of the picture width float maxheight = outheight;//expected output of the picture height float srcratio = srcwidth/srcheight;
float outratio = maxwidth/maxheight; float actualoutwidth = srcwidth;//The final output of the picture width float actualoutheight = srcheight;//The final output of the picture height if (srcwidth > MaxWidth | | sr Cheight > MaxHeight) {if (Srcratio < outratio) {actualoutheight = maxheight; actualoutwidth = Actualoutheight * sr
Cratio; else if (Srcratio > Outratio) {actualoutwidth = maxwidth; actualoutheight = Actualoutwidth/srcratio;} else {ACTU
Aloutwidth = MaxWidth;
Actualoutheight = MaxHeight; }//Calculate samplesize options.insamplesize = computsamplesize (options, Actualoutwidth, actualoutheight); 

To facilitate understanding of the above code, give an extreme example:

If the original picture width is srcwidth=40, High is srcheight=20. The expected output width is maxwidth=300, High is maxheight=10. So srcratio=40:20=2,outratio=300:10=30. Obviously Srcratio<outratio, then our actual final output picture size should be maxheight (10) as the Actualoutheight = MaxHeight, and finally according to the ratio of the original figure Actualoutwidth =actualoutheight*srcratio = 10*40/20=20, last obtained actualoutwidth=20. The 20:10=2 of the final output picture is the same as the width ratio of the original picture. In other cases, this is not a detailed explanation.

Quality compression of a picture

In this case, the Android Bitmap Class API interface has the Compress method

public boolean compress (compressformat format, int quality, OutputStream stream)

Three parameters of the understanding should not be difficult, you can view the official Doc document. The Compress method mainly controls the pixel quality of the input into the stream through the quality.

This scenario would be appropriate for a picture that you want to output that is not larger than a certain value, because we can use the loop to determine whether the compressed size is greater than the fixed value and, if satisfied, to reduce quality continue to perform compress operations. The core code is as follows:

Perform lossy compression
bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
int options_ = m;
Actualoutbitmap.compress (Bitmap.CompressFormat.JPEG, Options_, BAOs);//Mass compression method, the compressed data stored in the BAOs (100 means not compressed, 0 to the minimum)
int baoslength = Baos.tobytearray (). length;
while (baoslength/1024 > MaxFileSize) {//loops to determine if the picture is larger than maxmemmorrysize after compression, greater than the continued compression
Baos.reset ();/ Resetting BAOs the content before the next write overwrite
options_ = Math.max (0, Options_-10);//The picture quality is reduced by actualoutbitmap.compress each time
( Bitmap.CompressFormat.JPEG, Options_, BAOs)//Save compressed picture to BAOs
baoslength = Baos.tobytearray (). length;
if (Options_ = = 0)//If the image quality has been reduced to a minimum, no longer compression break
;

It takes time to compress a large image, so you should consider compressing it into a background thread, and you can solve the problem without high concurrency requirements using asynctask.

Core code:

Private class Compresstask extends Asynctask<string, Void, string> {
@Override
protected String Doinbackground (String ... params) {return
compressimage ();//Perform a compression operation
}
@Override
protected void OnPreExecute () {
if (Compresslistener!= null) {
compresslistener.oncompressstart ();//Listener callback (start compression)
}
}
@Override
protected void OnPostExecute (String imageoutpath) {
if (Compresslistener!= null) {
Compresslistener.oncompressend (Imageoutpath);//Listener callback (compression end)
}
}

The appropriate encapsulation code can be passed through the execution in the activity

Lgimgcompressor.getinstance (This). Withlistener (This). Starcompress (Uri.fromfile (ImageFile). toString (), Outwidth, Outheight,maxfilesize);

To start the compression task

Written in the last

In order to achieve the best compression results, the above two schemes can be carried out simultaneously. If the compression takes a long time, the compression process needs to be put into the background thread for execution.

I wrote a simple demo program, the implementation of the functions are:

1. Open the camera to take photos

2. Specify where the photos are stored

3. Compress the photos to the specified directory

4. Use Asynctask to perform compression operations

5. Display compressed photos and related information to the foreground activity

Because this version uses the Asynctask asynchronous task to execute the compress, and Asynctask due to the Android version of the split problem some versions are multi-threaded, some versions are single-threaded, is also drunk, in short this version for a single compression task is not a lot of cases, If you need to handle a large data compression task, you need to consider using a thread pool to handle it.

In addition, how to combine service and multithreading will be specified in the next article.

Demo Open source GitHub address is as follows:

Lgimagecompressor

The above is a small set to introduce the Android image compression upload the basic knowledge of the article, I hope to help you, if you want to learn more information please pay attention to cloud Habitat community website!

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.