Bitmap
Android中图片是以Bitmap(位图)形式存在,位图常见的文件格式有:.bmp .jpg .png .gif 。
Bitmap的大小计算 = 图片的长度图片的宽度单位像素所占用的字节数。
Bitmap的优缺点
优点:色彩变化丰富,可以改变任何形状的区域色彩显示效果。
缺点:放大和缩小都会引起像素的增加和缩小,这样会使图片出现失真或者锯齿形。另一个缺点就是像素越高数据量越大占用的内存越大。
常用压缩方法
质量压缩
质量压缩是不会改变图片的宽高(像素),是去改变图片的位深和透明度的。
png是无损压缩的,所以质量压缩对png是不起作用的
/**
* 质量压缩
* 降低图片的质量,不会减少图片的像素,改变图片的位深和透明度,没有改变像素大小,所以不会减少占据的内存大小。
*/
private void qualityCompress(Bitmap.CompressFormat format, int quality, String type) {
try {
File file = new File(Environment.getExternalStorageDirectory(), "test_" + quality + format + "_" + type + ".jpg");
//得到一个文件输入流
mFileOutputStream = new FileOutputStream(file);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_pic);
// 图片的格式 quality是压缩完之后保存图片设置的质量参数 png是无损压缩,quality参数对png无效
bitmap.compress(format, quality, mFileOutputStream);
} catch (FileNotFoundException exception) {
exception.printStackTrace();
} finally {
if (mFileOutputStream != null) {
try {
mFileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
采样率压缩
降低图片的像素。数值越高,图片像素越低。
/**
* 尺寸压缩中的采样率压缩
* 改变了像素,减少了图片占用的内存,同样照片的清晰度也降低了。
* inSampleSize = 2 内存将减少 1/4 内存大小 = 图片宽/inSampleSize * 图片高/inSampleSize * 单位像素占用的字节大小
*/
private void loadImage() {
BitmapFactory.Options options = new BitmapFactory.Options();
//设置为true 并会将图片加载到内存中,但是可以获取到图片的宽和高 通过options
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.ic_pic, options);
int outWidth = options.outWidth;
int outHeight = options.outHeight;
Log.d(TAG, "loadImage: width = " + outWidth);
Log.d(TAG, "loadImage: height = " + outHeight);
//这个地方根据获取到大小和想要显示的大小做缩放
options.inSampleSize = calculateInSampleSize(options, 200, 200);
Log.d(TAG, "loadImage: inSampleSize = " + options.inSampleSize);
//设置为false 这回再去解码图片可以将其读取到内存中了。
options.inJustDecodeBounds = false;
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_pic, options);
File file = new File(Environment.getExternalStorageDirectory(), "text_" + "just_100_no_inSampleSize.jpg");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// mImageView.setImageBitmap(mBitmap);
}
/**
* 计算图片的缩放比例
*
* @param options
* @param reqHeight
* @param reqWidth
*/
private int calculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) {
int height = options.outHeight;
int width = options.outWidth;
//缩放的比例
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
int halfHeight = height / 2;
int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
缩放法压缩
减小图片的像素,生成的图片file的大小也变小了。
/**
* 尺寸压缩中的 按缩放比压缩 这里的缩放比是事先定义好的 和采样率相比 采样率是根据给定的预期大小去计算缩放比
*
* @param mBitmap
* @param mFile
*/
private void compressBitmapToFile(Bitmap mBitmap, File mFile) {
//设置压缩倍数
int ratio = 2;
//压缩Bitmap到对应的尺寸 压缩格式 ARGB_8888 4字节 一个像素需要4个字节来存储
Bitmap resultBitmap = Bitmap.createBitmap(mBitmap.getWidth() / ratio, mBitmap.getHeight() / ratio, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
Rect rect = new Rect(0, 0, mBitmap.getWidth() / ratio, mBitmap.getHeight() / ratio);
canvas.drawBitmap(mBitmap, null, rect, null);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
File file = new File(Environment.getExternalStorageDirectory(), "test_compress_100.jpg");
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
try {
mFileOutputStream1 = new FileOutputStream(file);
mFileOutputStream1.write(byteArrayOutputStream.toByteArray());
mFileOutputStream1.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (mFileOutputStream1 != null) {
try {
mFileOutputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}