日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )

發布時間:2025/6/17 Android 22 豆豆

文章目錄

  • 一、 圖片質量壓縮
  • 二、 圖片尺寸壓縮
  • 三、 Android 10 文件訪問
  • 四、 完整源碼示例



上一篇博客 【Android 內存優化】圖片文件壓縮 ( Android 原生 API 提供的圖片壓縮功能能 | 圖片質量壓縮 | 圖片尺寸壓縮 ) 簡要介紹了 圖片文件壓縮格式 , 以及 Android 提供的圖片質量 , 尺寸壓縮 API , 本博客中使用該 API 進行圖片壓縮 ;





一、 圖片質量壓縮



圖片質量壓縮步驟 :


① 創建輸出流 : 創建一個文件輸出流 , 也可是是網絡輸出流 ;

FileOutputStream fos = new FileOutputStream(path);

② 加載文件 : 從 Assets , 資源文件 , SD 卡 , 中 解碼圖片文件為內存中的 Bitmap 對象 ; 這里從資源文件中加載 ;

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);

③ 壓縮圖片 : 調用 Bitmap 對象的 compress 方法 , 壓縮圖片 ;

bitmap.compress(compressFormat, quality, fos);



二、 圖片尺寸壓縮



圖片尺寸壓縮流程 :


① 加載文件 : 從 Assets , 資源文件 , SD 卡 , 中解碼圖片文件為內存中的 Bitmap 對象 ; 這里從資源文件中加載 ;

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);

② 圖片尺寸壓縮 : 調用 Bitmap 對象的 createScaledBitmap 方法 , 將目標寬高作為參數傳入 , 并使用雙線性濾波器算法 , 該算法能大幅度提供壓縮后的圖片質量 , 并且開銷較少 , 官方建議開啟該算法 ;

bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);



三、 Android 10 文件訪問



文件存儲相關官方參考資料 :

  • Android 11 中的存儲機制更新
  • Android storage use cases and best practices
  • 應用數據和文件

將圖片壓縮后 , 存儲到 SD 卡中 , 這里 涉及到了在 Android 10 系統中動態申請權限 , 設置舊的存儲訪問策略 ( 該策略將在 Android 11 中無效 ) ;

這里簡要介紹暫時性的解決方案 ;


1. AndroidManifest.xml 中配置 SD 卡權限 , 及舊存儲策略 :


① SD 卡權限 : 配置 SD 卡讀寫權限 ;

<!-- SD 卡訪問權限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

② 舊存儲策略 : 配置在 application 標簽中 , 特別注意該策略將在 Android 11 中廢棄 ;

android:requestLegacyExternalStorage="true"

③ 完整配置 :

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.pc"><!-- SD 卡訪問權限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- android:requestLegacyExternalStorage="true" 配置舊存儲策略 , Android 11 將禁止該功能 --><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"android:requestLegacyExternalStorage="true"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

2 . 在 Activity 中動態申請權限 : 在 Activity 中調用 initPermissions(); 方法 , 即可動態申請 SD 卡訪問權限 ;

/*** 需要獲取的權限列表*/private String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};/*** 動態申請權限的請求碼*/private static final int PERMISSION_REQUEST_CODE = 888;/*** 動態申請權限*/@RequiresApi(api = Build.VERSION_CODES.M)private void initPermissions() {if (isLacksPermission()) {//動態申請權限 , 第二參數是請求嗎requestPermissions(permissions, PERMISSION_REQUEST_CODE);}}/*** 判斷是否有 permissions 中的權限* @return*/@RequiresApi(api = Build.VERSION_CODES.M)public boolean isLacksPermission() {for (String permission : permissions) {if(checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){return true;}}return false;}

執行完上述三個步驟的操作

  • 配置權限
  • 設置舊存儲策略
  • 動態申請權限

即可在 Android 10 中訪問 SD 卡 , 如果在 Android 11 訪問 , 查看章節開始的文檔 ;





四、 完整源碼示例



圖片壓縮源碼示例 :

壓縮質量 : 下圖中的圖片壓縮都壓縮成最低質量的圖片 ;

package kim.hsl.pc;import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity;import android.Manifest; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.widget.TextView;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;public class MainActivity extends AppCompatActivity {static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.sample_text);tv.setText(stringFromJNI());// 初始化權限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {initPermissions();}// 將圖片壓縮成 JPEG 格式, 不縮放compressBitmap(R.drawable.blog, Bitmap.CompressFormat.JPEG, 0,Environment.getExternalStorageDirectory() + "/blog_jpeg.jpeg",0, 0);// 將圖片壓縮成 WEBP 格式compressBitmap(R.drawable.blog, Bitmap.CompressFormat.WEBP, 0,Environment.getExternalStorageDirectory() + "/blog_webp.webp",0, 0);// 將圖片壓縮成 PNG 格式compressBitmap(R.drawable.blog, Bitmap.CompressFormat.PNG, 0,Environment.getExternalStorageDirectory() + "/blog_png.png",0, 0);// 將圖片寬高各壓縮一半compressBitmap(R.drawable.blog, Bitmap.CompressFormat.PNG, 0,Environment.getExternalStorageDirectory() + "/blog_png_half.png",995, 510);}/*** 壓縮圖片, 并將壓縮結果保存到指定文件* @param resId 圖片資源* @param compressFormat 圖片壓縮格式* @param quality 壓縮質量* @param path 文件保存路徑*/public void compressBitmap(int resId, Bitmap.CompressFormat compressFormat,int quality, String path, int width, int height){// 從資源文件中加載一張圖片Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);// 如果傳入的尺寸參數大于 0, 那么壓縮尺寸if(width > 0 && height > 0){bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);}// 用于寫出壓縮后的圖片到文件中FileOutputStream fos = null;try {// 打開文件輸出流fos = new FileOutputStream(path);// 圖片壓縮操作// 如果圖片格式是 PNG 格式, 會忽略 質量 參數bitmap.compress(compressFormat, quality, fos);} catch (FileNotFoundException e) {e.printStackTrace();Log.i("TAG", "文件輸出流打開失敗");}finally {if(fos != null){try {fos.close();} catch (IOException e) {e.printStackTrace();Log.i("TAG", "文件輸出流關閉失敗");}}}}public native String stringFromJNI();/*** 需要獲取的權限列表*/private String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};/*** 動態申請權限的請求碼*/private static final int PERMISSION_REQUEST_CODE = 888;/*** 動態申請權限*/@RequiresApi(api = Build.VERSION_CODES.M)private void initPermissions() {if (isLacksPermission()) {//動態申請權限 , 第二參數是請求嗎requestPermissions(permissions, PERMISSION_REQUEST_CODE);}}/*** 判斷是否有 permissions 中的權限* @return*/@RequiresApi(api = Build.VERSION_CODES.M)public boolean isLacksPermission() {for (String permission : permissions) {if(checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){return true;}}return false;} }

壓縮結果分析 :


① 壓縮后的 PNG 格式 : 2.63 MB ;

② 壓縮后的 JPEG 格式 : 119 KB ;

③ 壓縮后的 WEBP 格式圖片 : 102 KB ;

④ 尺寸壓縮圖片 : 219 KB ;

壓縮格式中 PNG > JPEG > WEBP 格式 ;

PNG 圖片不能壓縮 , 這里顯示的大小是原圖大小 , 非常大 ;

總結

以上是生活随笔為你收集整理的【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。