Android圖片壓縮幾種方式總結(jié)
Android圖片壓縮幾種方式總結(jié)
圖片壓縮在Android開發(fā)中很常見也很重要,防止圖片的OOM也是壓縮的重要原因。
首先看下Bitmap圖片文件的大小的決定因素:
Bitmap所占用的內(nèi)存 = 圖片長度 x 圖片寬度 x 一個(gè)像素點(diǎn)占用的字節(jié)數(shù)。3個(gè)參數(shù),任意減少一個(gè)的值,就達(dá)到了壓縮的效果。
接下來看下Bitmap圖片的幾種格式的特點(diǎn):
ALPHA_8
表示8位Alpha位圖,即A=8,一個(gè)像素點(diǎn)占用1個(gè)字節(jié),它沒有顏色,只有透明度
ARGB_4444
表示16位ARGB位圖,即A=4,R=4,G=4,B=4,一個(gè)像素點(diǎn)占4+4+4+4=16位,2個(gè)字節(jié)
ARGB_8888
表示32位ARGB位圖,即A=8,R=8,G=8,B=8,一個(gè)像素點(diǎn)占8+8+8+8=32位,4個(gè)字節(jié)
RGB_565
表示16位RGB位圖,即R=5,G=6,B=5,它沒有透明度,一個(gè)像素點(diǎn)占5+6+5=16位,2個(gè)字節(jié)
如果進(jìn)行圖片格式的壓縮的話,一般情況下都是ARGB_8888轉(zhuǎn)為RGB565進(jìn)行壓縮。
寫了一個(gè)工具類,基本上列舉了android上圖片的幾種基本壓縮方式:
1.質(zhì)量壓縮
2.采樣率壓縮
3.尺寸壓縮
4.Matrix壓縮
5.圖片格式的壓縮,例如PNG和JPG保存后的圖片大小是不同的
public class Utils {
/**
* 采樣率壓縮
*
* @param bitmap
* @param sampleSize 采樣率為2的整數(shù)倍,非整數(shù)倍四舍五入,如4的話,就是原圖的1/4
* @return 尺寸變化
*/
public static Bitmap getBitmap(Bitmap bitmap, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
Log.i("info", "圖片大小:" + bit.getByteCount());//2665296 10661184
return bit;
}
/**
* 圖片質(zhì)量壓縮
*
* @param bitmap
* @param quality
* @return 尺寸不變,質(zhì)量變小
*/
public static Bitmap compressByQuality(Bitmap bitmap, int quality) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Log.i("info", "圖片大?。? + bit.getByteCount());//10661184
return bit;
}
/**
* 圖片質(zhì)量壓縮
*
* @param src
* @param maxByteSize
* @return
*/
public static Bitmap compressByQuality(Bitmap src, long maxByteSize) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int quality = 100;
src.compress(Bitmap.CompressFormat.JPEG, quality, baos);
while (baos.toByteArray().length > maxByteSize && quality > 0) {
baos.reset();
src.compress(Bitmap.CompressFormat.JPEG, quality -= 5, baos);
}
if (quality < 0) return null;
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
return bit;
}
public static Bitmap compressByFormat(Bitmap bitmap, int format) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Log.i("info", "圖片大?。? + bit.getByteCount());//10661184
return bit;
}
/**
* Matrix縮放
*
* @param bitmap
* @param scaleWidth
* @param scaleHeight
* @return 尺寸和大小變化
*/
public static Bitmap getBitmapBySize(Bitmap bitmap, float scaleWidth, float scaleHeight) {
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap bit = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
Log.i("info", "圖片大小:" + bit.getByteCount());
return bit;
}
/**
* 按照?qǐng)D片格式配置壓縮
*
* @param path
* @param config ALPHA_8,ARGB_4444,ARGB_8888,RGB_565;
* @return RGB_565比ARGB_8888節(jié)省一半內(nèi)存
*/
public static Bitmap getBitmapByFormatConfig(String path, Bitmap.Config config) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = config;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
Log.i("info", "圖片大?。? + bitmap.getByteCount());
return bitmap;
}
/**
* 指定大小縮放
*
* @param bitmap
* @param width
* @param height
* @return
*/
public static Bitmap getBitmapByScaleSize(Bitmap bitmap, int width, int height) {
Bitmap bit = Bitmap.createScaledBitmap(bitmap, width, height, true);
Log.i("info", "圖片大?。? + bit.getByteCount());
return bit;
}
/**
* 通過保存格式壓縮
*
* @param bitmap
* @param format JPEG,PNG,WEBP
* @return
*/
public static Bitmap getBitmapByFormat(Bitmap bitmap, Bitmap.CompressFormat format) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(format, 100, baos);
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Log.i("info", "圖片大?。? + bit.getByteCount());
return bit;
}
/**
* 文件加載壓縮
*
* @param filePath
* @param inSampleSize
* @return
*/
public static Bitmap getBitmap(String filePath, int inSampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);//此時(shí)不耗費(fèi)和占用內(nèi)存
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
public static Bitmap getBitmap(String filePath) {
return BitmapFactory.decodeFile(filePath);
}
public static Bitmap view2Bitmap(View view) {
if (view == null) return null;
Bitmap ret = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(ret);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return ret;
}
public static void saveBitmap(Bitmap bitmap) {
File file = new File(Environment.getExternalStorageDirectory() + "/img.jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void saveBitmap(Bitmap bitmap,Bitmap.CompressFormat format) {
File file = new File(Environment.getExternalStorageDirectory() + "/img.jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(format, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Android下拉阻尼效果實(shí)現(xiàn)原理及簡單實(shí)例
這篇文章主要為大家詳細(xì)介紹了Android下拉阻尼效果實(shí)現(xiàn)原理及簡單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
Android編程獲取手機(jī)后臺(tái)運(yùn)行服務(wù)的方法
這篇文章主要介紹了Android編程獲取手機(jī)后臺(tái)運(yùn)行服務(wù)的方法,涉及Android針對(duì)系統(tǒng)服務(wù)的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
android scrollview 滑動(dòng)到頂端或者指定位置的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猘ndroid scrollview 滑動(dòng)到頂端或者指定位置的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04
Windows下搭建Flutter開發(fā)環(huán)境
這篇文章介紹了Windows下搭建Flutter開發(fā)環(huán)境的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-11-11
Android ListView實(shí)現(xiàn)下拉頂部圖片變大效果
這篇文章主要為大家詳細(xì)介紹了Android ListView實(shí)現(xiàn)下拉頂部圖片變大,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android 接收推送消息跳轉(zhuǎn)到指定頁面的方法
這篇文章主要介紹了Android 接收推送消息跳轉(zhuǎn)到指定頁面的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
Android App中的GridView網(wǎng)格布局使用指南
GridView布局所實(shí)現(xiàn)的就是類似于九宮格的矩陣界面效果,下面整理了Android App中的GridView網(wǎng)格布局使用指南,包括分割線的添加與自定義GridView的實(shí)現(xiàn)等技巧,需要的朋友可以參考下2016-06-06
Android實(shí)現(xiàn)讀取相機(jī)(相冊(cè))圖片并進(jìn)行剪裁
在 Android應(yīng)用中,很多時(shí)候我們需要實(shí)現(xiàn)上傳圖片,或者直接調(diào)用手機(jī)上的拍照功能拍照處理然后直接顯示并上傳功能,下面將講述調(diào)用相機(jī)拍照處理圖片然后顯示和調(diào)用手機(jī)相冊(cè)中的圖片處理然后顯示的功能2015-08-08
Android多線程+單線程+斷點(diǎn)續(xù)傳+進(jìn)度條顯示下載功能
這篇文章主要介紹了Android多線程+單線程+斷點(diǎn)續(xù)傳+進(jìn)度條顯示下載功能,需要的朋友可以參考下2017-06-06

