最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android WebP 圖片壓縮與傳輸

 更新時間:2016年08月30日 15:50:59   作者:Wesley-H  
本文主要講解Android WebP 圖片壓縮與傳輸,這里對WebP圖片格式以及如何實現壓縮和傳輸,做了詳細講解,有需要的小伙伴可以參考下

1. 簡介

直到4g時代,流量依然是寶貴的東西。而移動網絡傳輸中,最占流量的一種載體:圖片,成為了我們移動開發(fā)者不得不關注的一個問題。

我們關注的問題,無非是圖片體積和質量如何達到一個比較和諧的平衡,希望得到質量不錯的圖片同時體積還不能太大。

走在時代前列的谷歌給出了一個不錯的答案——WebP。

WebP是一種圖片文件格式,在相同的壓縮指標下,webp的有損壓縮能比jpg小 25-34%。而在我自己的測試里,有時候能小50%。

2. 大企業(yè)背書

WebP在2010年發(fā)布第一個版本,到現在已經6年了,谷歌旗下的各種網站G+、以及非常有代表性的YouTube,他的視頻文件格式WebM就是基于WebP構造的。

據說騰訊、淘寶、美團也有部分應用。

3. Android 端 JPG 轉換 WebP

RxJava線程轉換:

 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);//分別是圖片路徑,寬度高度,質量,和圖片類型,重點在這里。
 File webp = new File(path, imgName + "compress.webp");
 FileUtils.writeByteArrayToFile(webp, bytes1);
 Log.i("compress", "webp finish");
 } catch (IOException e) {
 e.printStackTrace();
 }
 }

我的測試機器也是Oneplus 1 ,CM13,所以需要獲取相應的權限。

利用RxJava來做線程操作,在io線程里做了耗時操作。

public static byte[] compressBitmapToBytes(String filePath, int reqWidth, int reqHeight, int quality, Bitmap.CompressFormat 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 = new 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;
 }

根據輸入的寬高值計算分辨率的縮小比例,再根據輸入的壓縮質量數值,壓縮圖片,獲得壓縮后bitmap,然后再將其保存成本地文件。

這是非常常見的圖片壓縮手段。

4. WebP對比

我用我日常生活里拍下的照片來做簡單的對比測試,不是特別嚴謹,僅供簡單的參考。

拍照設備是刷了CM13的 一加 1 。拍照場景都是日常生活特別常見的。

以下是原圖預覽,就不一個個放出來了,太大。

縮小分辨率,同時壓縮質量

文件名 照片原圖 壓縮后jpg 壓縮后webp 壓縮比
1.jpg 5760 kb 98 kb 74 kb 24.49%
2.jpg 4534 kb 64 kb 35 kb 45.31%
3.jpg 4751 kb 93 kb 68 kb 26.88%
4.jpg 7002 kb 121 kb 95 kb 21.49%
5.jpg 5493 kb 111 kb 91 kb 18.02%

平均壓縮比是:27.24%

按照原圖大小,不縮小分辨率,僅壓縮質量。

文件名 照片原圖 壓縮后jpg 壓縮后webp 壓縮比
3.jpg 4751 kb 796 kb 426 kb 46.48%

至此,我們就非常方便的使用了webp來對圖片進行更加極致的壓縮,兼顧了圖片體積和質量。

呃,csdn不支持上傳webp的圖片。你們可以看壓縮包。
我嫌麻煩,可能不會傳壓縮包了……所以,你們看截圖吧~

睜大眼睛對比一下有啥區(qū)別,不縮小分辨率,僅壓縮質量,這個3.jpg可是有46.48%的壓縮比噢。
這個場景是晚上在燈光充足的室內吃飯拍的。

5. 用Gzip再壓縮

剛剛是針對本地圖片的壓縮,接下來,我們需要將圖片傳輸到服務器。這個過程依然有優(yōu)化空間,就是利用Gzip。

Gzip的作用對象是整個請求體,具體來說是對請求體中的內容進行可逆的壓縮,類似pc上zip的那種。

Gzip壓縮的請求體,需要加入相應的header: 「Content-Encoding:gzip」。
這事情Retrofit會幫你做好。

后臺服務器接收到在此類型的請求,就會對請求體解壓,因此需要后端的支持。

另外要注意的是,Gzip針對比較大的請求體壓縮效果不錯,尤其是未經過壓縮的純文本類型。

如果請求本來就很小,那么就不要使用gzip壓縮了,壓縮包自己的元數據可能比你的請求體還大,得不償失。你可以自己測試一下,我估計zip和gzip的壓縮字典比較類似,可以直接在pc上做測試。

6. Retrofit對請求Gzip壓縮

網絡請求方面,我項目里使用Retrofit (OKHttp) + RxJava。

Retrofit的Gzip壓縮,本質上是通過OKHttp的攔截器來完成的。

0攔截請求
1加入header
2壓縮請求
3發(fā)送出去

搞定,方便。

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. 請求體抓包對比

我會用Fiddler4 監(jiān)測整個請求過程,以方便我們得知實際傳輸了多大的數據。

上傳的具體代碼就不發(fā)了,這個不是重點。

我把請求抓包之后,把request這個保存下來。

這是同時上傳兩張圖片的大小

文件名 請求體大小
WebP+Gzip 169kb
WebP 222kb

用Gzip壓縮 比不加Gzip 又小 23% ! jpg我就不發(fā)了,可以按照前面的估算一下~

WebP比Jpg小27%,然后gzip+webp又比單純的webp小23%,節(jié)省下來的流量多可觀啊!

8. 最后

WebP默認只支持Android 4.0以上,現在項目最低支持的版本是16,所以沒什么問題。如果你的項目最低要支持到2.0,好像也有第三方支持,但是我建議你抓產品出去打一頓。

在我們的項目里,iOS沒用使用該技術。

根據下面的參考鏈接的數據以及我本人測試數據來看,WebP不僅大大的節(jié)省了用戶的流量,同時還可以加速圖片傳輸速度。就照片傳輸的角度來看,是非常有利的。

如果還是有人告訴你:“IOS做不了,不做了。”,“后臺XXX不做了。”

我建議你抓產品出去打一頓。

相關參考:

http://isux.tencent.com/introduction-of-webp.html(產品經理看這個)

http://blog.csdn.net/GeekLei/article/details/41147479 (后臺需要看這個)

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 (他們表示IOS也沒有用上)

http://blog.csdn.net/mingchunhu/article/details/8155742(Android全部都要看)

相關文章

  • Android仿微信聯系人列表字母側滑控件

    Android仿微信聯系人列表字母側滑控件

    這篇文章主要為大家詳細介紹了Android仿微信聯系人列表字母側滑控件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 基于界面適配華為手機的虛擬按鍵的解決方法

    基于界面適配華為手機的虛擬按鍵的解決方法

    下面小編就為大家分享一篇基于界面適配華為手機的虛擬按鍵的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Kotlin開發(fā)實戰(zhàn)之hello world

    Kotlin開發(fā)實戰(zhàn)之hello world

    這篇文章主要為大家詳細介紹了Kotlin開發(fā)實戰(zhàn)之hello world的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Android 仿微信數字鍵盤

    Android 仿微信數字鍵盤

    大部分的金融App會對默認的數字鍵盤進行處理,以實現自定義的數字安全鍵盤?;诖?,本文對對微信數字鍵盤樣式進行了仿寫,實現了一套自定義的數字安全鍵盤(支持隨機數字分布)。
    2021-05-05
  • Android自定義ScrollView實現放大回彈效果

    Android自定義ScrollView實現放大回彈效果

    這篇文章主要為大家詳細介紹了Android自定義ScrollView實現放大回彈效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Android studio 廣播的簡單使用代碼詳解

    Android studio 廣播的簡單使用代碼詳解

    這篇文章主要介紹了Android studio 廣播的簡單使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java4Android開發(fā)教程(一)JDK安裝與配置

    Java4Android開發(fā)教程(一)JDK安裝與配置

    本文是Android開發(fā)系列教程的第一篇,主要為大家?guī)淼氖情_發(fā)環(huán)境的準備工作,JDK安裝與配置圖文教程,非常的詳細,有需要的朋友可以參考下
    2014-10-10
  • 5個Android開發(fā)中比較常見的內存泄漏問題及解決辦法

    5個Android開發(fā)中比較常見的內存泄漏問題及解決辦法

    本文主要介紹了5個Android開發(fā)中比較常見的內存泄漏問題及解決辦法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Android調用密碼鎖屏校驗的流程代碼詳解

    Android調用密碼鎖屏校驗的流程代碼詳解

    這篇文章主要介紹了Android調用密碼鎖屏校驗的流程代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • android與asp.net服務端共享session的方法詳解

    android與asp.net服務端共享session的方法詳解

    這篇文章主要給大家介紹了關于android與asp.net服務端如何共享session的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋們下面隨著小編來一起學習學習下吧。
    2017-09-09

最新評論

赣榆县| 新田县| 铜川市| 恩平市| 阳泉市| 江西省| 芮城县| 涿州市| 双牌县| 武功县| 阜新| 分宜县| 大厂| 绥芬河市| 滦南县| 全州县| 郸城县| 鱼台县| 紫阳县| 互助| 图们市| 灵丘县| 确山县| 石景山区| 黎城县| 高陵县| 宣恩县| 平凉市| 孝感市| 蓝田县| 兴和县| 衡阳市| 泸水县| 崇明县| 翼城县| 镇江市| 沐川县| 泸定县| 萨迦县| 临朐县| 云和县|