1.采样率压缩
采样率压缩是改变了图片的像素,他是通过先读取图片的边,然后在自己设定图片的边,然后根据设定,读取图片的像素。在读取的时候,并不是所有的像素都读取,而是由选择的。所以这种方式减少了像素的个数,能改变图片在内存中的占用大小
/**
* 采样率压缩
*/
public static Bitmap inSampleCompress(String filePath,int inSampleSize){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //为True时,不会真正加载图片,而是得到图片的宽高信息
options.inSampleSize = 1;
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = computeSize(options);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
// 开源项目 鲁班Luban 的算法
private static int computeSize(BitmapFactory.Options options) {
int srcWidth = options.outWidth;
int srcHeight = options.outHeight;
srcWidth = srcWidth % 2 == 1 ? srcWidth + 1 : srcWidth;
srcHeight = srcHeight % 2 == 1 ? srcHeight + 1 : srcHeight;
int longSide = Math.max(srcWidth, srcHeight);
int shortSide = Math.min(srcWidth, srcHeight);
float scale = ((float) shortSide / longSide);
if (scale <= 1 && scale > 0.5625) {
if (longSide < 1664) {
return 1;
} else if (longSide < 4990) {
return 2;
} else if (longSide > 4990 && longSide < 10240) {
return 4;
} else {
return longSide / 1280 == 0 ? 1 : longSide / 1280;
}
} else if (scale <= 0.5625 && scale > 0.5) {
return longSide / 1280 == 0 ? 1 : longSide / 1280;
} else {
return (int) Math.ceil(longSide / (1280.0 / scale));
}
}
保存Bitmap图片到文件
public static void saveBitmap(Bitmap bitmap,File file){
ByteArrayOutputStream stream =new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
try {
if (file.exists()){
file.delete();
}else{
file.createNewFile();
}
FileOutputStream fileOutputStream=new FileOutputStream(file);
fileOutputStream.write(stream.toByteArray());
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.尺寸压缩
通过缩放图片的像素,减小图片占用内存大小,这个比如用于缩略图
/**尺寸压缩
* @param bitmap 要压缩的图片
* @param ratio 压缩比例,值越大,图片的尺寸就越小
* @param file 压缩的图片保存地址
*/
public static void sizeCompressBitmap(Bitmap bitmap,int ratio,File file){
if (ratio<=0){
return;
}
Bitmap result=Bitmap.createBitmap(bitmap.getWidth()/ratio,bitmap.getHeight()/ratio, Bitmap.Config.ARGB_8888);
Canvas canvas =new Canvas();
Rect rect=new Rect(0,0,bitmap.getWidth()/ratio,bitmap.getHeight()/ratio);
canvas.drawBitmap(bitmap,null,rect,null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 把压缩后的数据存放到baos中
result.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
3.质量压缩
质量压缩,这个只是降低了图片的质量,但是像素是不会减小的
/** 质量压缩,
* @param bitmap 要压缩的图片
* @param file //压缩的图片保存地址
* Hint to the compressor, 0-100. 0 meaning compress for small size, 100 meaning compress for max quality. Some
* formats, like PNG which is lossless, will ignore the quality setting
* quality (0-100) 100是不压缩,值越小,压缩得越厉害
*/
public static void qualityCompressBitmap(Bitmap bitmap,File file){
//字节数组输出流
ByteArrayOutputStream baos =new ByteArrayOutputStream();
int quality=60;
//图片压缩后把数据放在stream中
bitmap.compress(Bitmap.CompressFormat.JPEG,quality, baos);
// int quality = 80;
// while (baos.toByteArray().length > MAX_SIZE) {
// baos.reset();
// bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
// quality -= 10;
// if(quality < 50){
// break;
// }
// }
try {
FileOutputStream fileOutputStream=new FileOutputStream(file);
fileOutputStream.write(baos.toByteArray());
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
4.旋转图片
private static Bitmap rotatingImage(Bitmap bitmap, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
/**
*
* 读取图片属性:旋转的角度
* @param path 图片绝对路径
* @return degree旋转的角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}