Android WebP image compression and transmission _android

Source: Internet
Author: User
Tags webp


1. Introduction



Until the 4g era, traffic is still a valuable thing. and mobile network transmission, the most account for the flow of a carrier: pictures, has become our mobile developers have to pay attention to a problem.



Our concern is nothing more than the picture volume and quality of how to achieve a more harmonious balance, hoping to get good quality pictures at the same time not too big.



Google, who walks in the forefront of the times, gives a good answer--webp.



WEBP is a picture file format, under the same compression index, WEBP lossy compression can be smaller than JPG 25-34%. And in my own tests, sometimes it can be as small as 50%.



2. Endorsement of large enterprises



WEBP released its first version in 2010, now 6 years, Google's various sites g+, and very representative of YouTube, his video file format WEBM is based on WEBP structure.



Tencent, Taobao and the United States are said to have some applications.



3. Android End JPG Conversion WebP



Rxjava Thread Conversions:


String[] imgs = new String[]{"1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"};
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/test/";
    @Override
    Protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
// test = Api.getBuilder().create(Test.class);
        String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE
                , Manifest.permission.READ_PHONE_STATE
                , Manifest.permission.CAMERA};
        If (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissions, 0);
        }
        Compress();
    }
    Private void compress() {
        Observable.from(imgs)
                .subscribeOn(Schedulers.io())
                .doOnNext(new Action1<String>() {
                    @Override
                    Public void call(String imgName) {
                        Compress(imgName);
                    }
                })
                .subscribe();
    }
    Private void compress(String imgName) {
        Try {
            File file = new File(path, imgName);
            Log.i("compress", "jpg start");
            Byte[] bytes = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.JPEG);
            File jpg = new File(path, imgName + "compress.jpg");
            FileUtils.writeByteArrayToFile(jpg, bytes);
            Log.i("compress", "jpg finish");
            Log.i("compress", "----------------------------------------- -----------");
            Log.i("compress", "webp start");
            Byte[] bytes1 = BitmapUtil.compressBitmapToBytes(file.getPath(), 600, 0, 60, Bitmap.CompressFormat.WEBP); // is the image path, width height, quality, and image type, respectively.
            File webp = new File(path, imgName + "compress.webp");
            FileUtils.writeByteArrayToFile(webp, bytes1);
            Log.i("compress", "webp finish");
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 

My test machine is also OnePlus 1, CM13, so I need to get the appropriate permissions.



Using Rxjava to do threading, time-consuming operations are done in IO threads.


public static byte[] Compressbitmaptobytes (String filePath, int reqwidth, int reqheight, int quality, bitmap.compressform
 At format) {Bitmap Bitmap = Getsmallbitmap (FilePath, Reqwidth, reqheight);
 Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
 Bitmap.compress (format, quality, BAOs);
 byte[] bytes = Baos.tobytearray ();
 Bitmap.recycle ();
 LOG.I (TAG, "Bitmap compressed success, size:" + bytes.length);
 return bytes; public static Bitmap Getsmallbitmap (String filePath, int reqwidth, int reqheight) {bitmapfactory.options Options = NE
 W bitmapfactory.options ();
 Options.injustdecodebounds = true;
 Bitmapfactory.decodefile (FilePath, Options);
 Options.insamplesize = calculateinsamplesize (options, Reqwidth, reqheight);
Options.injustdecodebounds = false;
 Options.inpreferqualityoverspeed = true;
 Return Bitmapfactory.decodefile (FilePath, Options); public static int calculateinsamplesize (bitmapfactory.options options, int reqwidth, int reqheight) {int h = options.Outheight;
 int w = options.outwidth;
 int insamplesize = 0;
 if (H > Reqheight | | w > reqwidth) {float Ratiow = (float) w/reqwidth;
 float Ratioh = (float) h/reqheight;
 insamplesize = (int) math.min (Ratioh, RATIOW);
 } insamplesize = Math.max (1, insamplesize);
 return insamplesize;
 }


According to the input of the width and height of the resolution to calculate the reduction ratio, and then according to the input compression quality value, compressed picture, get compressed bitmap, and then save the cost of the file.



This is a very common image compression method.



4. WEBP Contrast



I use the photos in my daily life to do a simple contrast test, not particularly rigorous, only for simple reference.



The camera device is a 1 brush CM13. Photo scenes are especially common in everyday life.



The following is a preview of the original, not one of them out, too big.






Reduce resolution, while compressing quality





file name Photo Artwork compress post jpg after compression webp Compression ratio
1.jpg 5760 kb MB kb MB kb 24.49%
2.jpg 4534 kb MB kb kb 45.31%
3.jpg 4751 kb kb MB kb 26.88%
4.jpg 7002 kb 121 kb kb 21.49%
5.jpg 5493 kb kb Mb 18.02%





Average compression ratio is: 27.24%



according to the original size, do not reduce the resolution , only the quality is compressed.





file name Photo Artwork compress post jpg after compression webp Compression ratio
3.jpg 4751 kb 796 kb 426 kb 46.48%





At this point, we are very convenient to use the WEBP to more extreme compression of the picture, taking into account the volume and quality of the picture.



Well, CSDN doesn't support uploading pictures of WEBP. You can look at the compressed package.
I am too troublesome, may not pass the compression package ... So, you can see the screenshot.



Open eyes contrast what is the difference, do not reduce the resolution, only compression quality, this 3.jpg but has 46.48% compression ratio oh.
The scene was taken at night in a well-lit room.









5. Use gzip to compress again



Just for the local image compression, next, we need to transfer the picture to the server. This process still has the optimization space, is uses the gzip.



The object of gzip is the entire request body, specifically to the content in the request body in a reversible compression, similar to the kind of zip on the PC.



Gzip compressed request body, need to add corresponding header:"content-encoding:gzip".
This matter retrofit will help you to do well.



When the backend server receives this type of request, it extracts the requested body and requires back-end support.



Also note that gzip is good for larger request body compression, especially for plain text types that are not compressed.



If the request is already very small, then do not use gzip compression, compressed the package of their own metadata may be larger than your request body, not worth the candle. You can test it yourself, I estimate that zip and gzip compression dictionaries are similar and can be tested directly on the PC.



6. Retrofit to request gzip compression



For network requests, I use retrofit (okhttp) + Rxjava in my project.



The retrofit gzip compression is essentially done through a okhttp interceptor.



0 Interception Request
1 Add header
2 Compression Request
3 Send out



Done, convenient.



Https://github.com/square/okhttp/wiki/Interceptors


/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
final class GzipRequestInterceptor implements Interceptor {
  @Override public Response intercept(Interceptor.Chain chain) throws IOException {
    Request originalRequest = chain.request();
    if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
      return chain.proceed(originalRequest);
    }
    Request compressedRequest = originalRequest.newBuilder()
        .header("Content-Encoding", "gzip")
        .method(originalRequest.method(), gzip(originalRequest.body()))
        .build();
    return chain.proceed(compressedRequest);
  }
  private RequestBody gzip(final RequestBody body) {
    return new RequestBody() {
      @Override public MediaType contentType() {
        return body.contentType();
      }
      @Override public long contentLength() {
        return -1; // We don't know the compressed length in advance!
      }
      @Override public void writeTo(BufferedSink sink) throws IOException {
        BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
        body.writeTo(gzipSink);
        gzipSink.close();
      }
    };
  }
}


7. The request body grasps the package to compare



I use FIDDLER4 to monitor the entire request process to make it easier for us to know how much data is actually being transmitted.



Upload the specific code will not be issued, this is not the point.



After I grabbed the bag, I saved the request.






This is the size of two pictures uploaded simultaneously





file name Request Body Size
Webp+gzip 169kb
WebP 222kb





With gzip compression than gzip and small 23%! JPG I will not hair, you can follow the previous estimate ~



WEBP than JPG 27%, and then gzip+webp than the simple WEBP small 23%, save the flow of more impressive Ah!



8. Finally



WEBP By default only supports Android more than 4.0, now the project's lowest support version is 16, so no problem. If your project is supported to a minimum of 2.0, there seems to be a third party support, but I suggest you grab the product and go out and play.



In our project, iOS doesn't use the technology.



According to the following reference link data and my own test data, WEBP not only greatly save the user's traffic, but also can speed up the picture transfer speed. In terms of photo transmission, it is very advantageous.



If someone tells you: "iOS can't do it, don't do it." "," The Backstage xxx does not do. ”



I suggest you grab the product and go out and play.



Related reference:



Http://isux.tencent.com/introduction-of-webp.html (Product manager look at this)



http://blog.csdn.net/GeekLei/article/details/41147479 (I need to see this in the background)



https://developers.google.com/speed/webp/



Http://www.infoq.com/cn/articles/sdk-optimazation?utm_campaign=infoq_content&utm_source=infoq&utm_ Medium=feed&utm_term (They say iOS doesn't work either)



http://blog.csdn.net/mingchunhu/article/details/8155742 (Android all to see)


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.