網(wǎng)站首頁 編程語言 正文
Android中圖片有四種屬性
ALPHA_8:每個像素占用1byte內(nèi)存
ARGB_4444:每個像素占用2byte內(nèi)存
ARGB_8888:每個像素占用4byte內(nèi)存 (默認)
RGB_565:每個像素占用2byte內(nèi)存
Android默認的顏色模式為ARGB_8888,這個顏色模式色彩最細膩,顯示質(zhì)量最高。但同樣的,占用的內(nèi)存也最大。所以在對圖片效果不是特別高的情況下使用RGB_565(565沒有透明度屬性)
Android目前常用圖片格式
有png,jpeg和webp
png:無損壓縮圖片格式,支持Alpha通道,Android切圖素材多采用該格式
jpeg:有損壓縮圖片格式,不支持背景透明,適用于照片等色彩豐富的(大圖壓縮,不適合logo)
webp:是一種同時提供了有損壓縮和無損壓縮的圖片格式,派生自視頻編碼格式VP8,從谷歌官網(wǎng)來看,無損webp平均比png小26%,有損的webp平均比jpeg小25%~34%,無損webp支持Alpha通道,有損webp在一定的條件下同樣支持,有損webp在Android4.0(API 14)之后支持,無損和透明在Android4.3(API18)之后支持
使用
大小壓縮
private Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設(shè)回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此時返回bm為空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//現(xiàn)在主流手機比較多是800*480分辨率,所以高和寬我們設(shè)置為
float hh = 800f;//這里設(shè)置高度為800f
float ww = 480f;//這里設(shè)置寬度為480f
//縮放比。由于是固定比例縮放,只用高或者寬其中一個數(shù)據(jù)進行計算即可
int be = 1;//be=1表示不縮放
if (w > h && w > ww) {//如果寬度大的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//設(shè)置縮放比例
//重新讀入圖片,注意此時已經(jīng)把options.inJustDecodeBounds 設(shè)回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//壓縮好比例大小后再進行質(zhì)量壓縮
}
質(zhì)量壓縮
注意:
第二次壓縮之前都要先清空 baos.reset(); 再進行壓縮
image.compress(Bitmap.CompressFormat.JPEG, quality, baos);
有時候我們采用質(zhì)量壓縮沒有效果,有可能是每次壓縮的質(zhì)量過小,所以我們可以嘗試修改壓縮質(zhì)量(quality)是10;
quality壓縮機提示,0-100。0表示壓縮小尺寸,100意味著最大質(zhì)量的壓縮。一些格式,如無損的PNG,將忽略質(zhì)量設(shè)定;
private Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 90;
int length = baos.toByteArray().length / 1024;
if (length>5000){
//重置baos即清空baos
baos.reset();
//質(zhì)量壓縮方法,這里100表示不壓縮,把壓縮后的數(shù)據(jù)存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, 10, baos);
}else if (length>4000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 20, baos);
}else if (length>3000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
}else if (length>2000){
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, 70, baos);
}
//循環(huán)判斷如果壓縮后圖片是否大于1M,大于繼續(xù)壓縮
while (baos.toByteArray().length / 1024>1024) {
//重置baos即清空baos
baos.reset();
//這里壓縮options%,把壓縮后的數(shù)據(jù)存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
//每次都減少10
options -= 10;
}
//把壓縮后的數(shù)據(jù)baos存放到ByteArrayInputStream中
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
//把ByteArrayInputStream數(shù)據(jù)生成圖片
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
混合方式壓縮
private Bitmap comp(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if( baos.toByteArray().length / 1024>1024) {//判斷如果圖片大于1M,進行壓縮避免在生成圖片(BitmapFactory.decodeStream)時溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//這里壓縮50%,把壓縮后的數(shù)據(jù)存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//開始讀入圖片,此時把options.inJustDecodeBounds 設(shè)回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//現(xiàn)在主流手機比較多是800*480分辨率,所以高和寬我們設(shè)置為
float hh = 800f;//這里設(shè)置高度為800f
float ww = 480f;//這里設(shè)置寬度為480f
//縮放比。由于是固定比例縮放,只用高或者寬其中一個數(shù)據(jù)進行計算即可
int be = 1;//be=1表示不縮放
if (w > h && w > ww) {//如果寬度大的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的話根據(jù)寬度固定大小縮放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//設(shè)置縮放比例
//重新讀入圖片,注意此時已經(jīng)把options.inJustDecodeBounds 設(shè)回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//壓縮好比例大小后再進行質(zhì)量壓縮
}
采樣率壓縮
采樣率壓縮是通過設(shè)置BitmapFactory.Options.inSampleSize,來減小圖片的分辨率,進而減小圖片所占用的磁盤空間和內(nèi)存大小。
設(shè)置的inSampleSize會導(dǎo)致壓縮的圖片的寬高都為1/inSampleSize,整體大小變?yōu)樵紙D片的inSampleSize平方分之一,當然,這些有些注意點:
- 1、inSampleSize小于等于1會按照1處理
- 2、inSampleSize只能設(shè)置為2的平方,不是2的平方則最終會減小到最近的2的平方數(shù),如設(shè)置7會按4進行壓縮,設(shè)置15會按8進行壓縮。
/**
*
* @param inSampleSize 可以根據(jù)需求計算出合理的inSampleSize
*/
public static void compress(int inSampleSize) {
File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
BitmapFactory.Options options = new BitmapFactory.Options();
//設(shè)置此參數(shù)是僅僅讀取圖片的寬高到options中,不會將整張圖片讀到內(nèi)存中,防止oom
options.inJustDecodeBounds = true;
Bitmap emptyBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize;
Bitmap resultBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
try {
FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
圖片保存到本地
/**
* 保存bitmap到本地
* @param context the context
* @param mBitmap the m bitmap
* @return string
*/
public static String saveBitmap(Context context, Bitmap mBitmap) {
String savePath;
File filePic;
try {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
savePath = SD_PATH;
} else {
savePath = context.getApplicationContext().getFilesDir().getAbsolutePath() + IN_PATH;
}
filePic = new File(savePath + DateTimeHelper.format(new Date(), "yyyyMMddHHmmss") + ".jpg");
Log.d("LUO", "圖片地址====" + filePic);
if (!filePic.exists()) {
filePic.getParentFile().mkdirs();
filePic.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePic);
//不壓縮,保存本地
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return filePic.getAbsolutePath();
}
原文鏈接:https://blog.csdn.net/qq_40945489/article/details/108681014
相關(guān)推薦
- 2022-10-06 Python?PaddlePaddle機器學(xué)習(xí)之求解線性模型_python
- 2022-03-15 eclipse文件上傳錯誤:the request doesn‘t contain a multip
- 2022-06-22 深入淺析C/C++?的條件編譯_C 語言
- 2022-10-14 element tree懶加載默認展開指定節(jié)點
- 2022-12-29 Android?Fragment的具體使用方式詳解_Android
- 2022-10-20 詳解Go?語言如何通過測試保證質(zhì)量_Golang
- 2022-04-27 為ABP框架配置數(shù)據(jù)庫_基礎(chǔ)應(yīng)用
- 2023-06-04 Kotlin比較與解釋Lazy與Lateinit的用法_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支