概述
Android实现图片压缩(大小与质量压缩以及图片保存)
这里写目录标题
- Android实现图片压缩(大小与质量压缩以及图片保存)
- 前言:
- 使用
- 图片保存到本地
前言:
-
Android中图片有四种属性,分别是:
ALPHA_8:每个像素占用1byte内存 ARGB_4444:每个像素占用2byte内存 ARGB_8888:每个像素占用4byte内存 (默认) RGB_565:每个像素占用2byte内存
Android默认的颜色模式为ARGB_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。所以在对图片效果不是特别高的情况下使用RGB_565(565没有透明度属性)
-
Android目前常用的图片格式有png,jpeg和webp
png:无损压缩图片格式,支持Alpha通道,Android切图素材多采用该格式 jpeg:有损压缩图片格式,不支持背景透明,适用于照片等色彩丰富的(大图压缩,不适合logo) webp:是一种同时提供了有损压缩和无损压缩的图片格式,派生自视频编码格式VP8,从谷歌官网来看,无损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 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
-
质量压缩
注意: 第二次压缩之前都要先清空 baos.reset(); 再进行压缩 image.compress(Bitmap.CompressFormat.JPEG, quality, baos); 有时候我们采用质量压缩没有效果,有可能是每次压缩的质量过小,所以我们可以尝试修改压缩质量(quality)是10; quality压缩机提示,0-100。0表示压缩小尺寸,100意味着最大质量的压缩。一些格式,如无损的PNG,将忽略质量设定;
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();
//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到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);
}
//循环判断如果压缩后图片是否大于1M,大于继续压缩
while (baos.toByteArray().length / 1024>1024) {
//重置baos即清空baos
baos.reset();
//这里压缩options%,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
//每次都减少10
options -= 10;
}
//把压缩后的数据baos存放到ByteArrayInputStream中
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
//把ByteArrayInputStream数据生成图片
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%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
-
采样率压缩
采样率压缩是通过设置BitmapFactory.Options.inSampleSize,来减小图片的分辨率,进而减小图片所占用的磁盘空间和内存大小。 设置的inSampleSize会导致压缩的图片的宽高都为1/inSampleSize,整体大小变为原始图片的inSampleSize平方分之一,当然,这些有些注意点: 1、inSampleSize小于等于1会按照1处理 2、inSampleSize只能设置为2的平方,不是2的平方则最终会减小到最近的2的平方数,如设置7会按4进行压缩,设置15会按8进行压缩。
/**
*
* @param inSampleSize
可以根据需求计算出合理的inSampleSize
*/
public static void compress(int inSampleSize) {
File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
BitmapFactory.Options options = new BitmapFactory.Options();
//设置此参数是仅仅读取图片的宽高到options中,不会将整张图片读到内存中,防止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();
}
最后
以上就是平常汽车为你收集整理的Android实现图片压缩(大小与质量压缩以及图片保存)前言:使用图片保存到本地的全部内容,希望文章能够帮你解决Android实现图片压缩(大小与质量压缩以及图片保存)前言:使用图片保存到本地所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复