1、BitmapFactory.Options中的属性
在进行图片压缩时,是通过设置BitmapFactory.Options的一些值来改变图片的属性的,以下我们来看看BitmapFactory.Options中经常使用的属性意思:
- options.inPreferredConfig - 设置Bitmap的偏好配置。值有Bitmap.Config.ARGB_8888,Bitmap.Config.ARGB_4444,Bitmap.Config.ARGB_8888。Bitmap.Config.RGB_565。默觉得ARGB_8888,顾名思义。这是设置Bitmap的显示质量的。
- options.outHeight - 得到该Bitmap的高。
- options.outWidth - 得到该Bitmap的宽。
- options.outMimeType - 得到该Bitmap的MIME值。
- options.inSampleSize - 压缩比例。假设options.inSampleSize = 4;那么压缩后的图片的宽和高都为原来图片的1/4。压缩后的图片的像素为原来图片的1/16。
- options.inJustDecodeBounds - 官方文档上是这样介绍的:
- If set to true, the decoder will return null (no bitmap), but
the out... fields will still be set, allowing the caller to query
the bitmap without having to allocate the memory for its pixels. - 意思就是:假设设置为true,那么使用BitmapFactory.decodeStream(InputStream is, Rect outPadding,
Options opts)或BitmapFactory.decodeXXX(....,Options opts)方法并不会真的返回一个Bitmap对象,而是返回null。尽管返回null,可是我们却能够通过options来获得该Bitmap的一些值。如它的宽、高、MimeType等值。这样就不必为Bitmap对象分配内存空间也能够获得它的Width和Height。从而节约内存。所以这个属性对我们压缩图片前进行检查大有帮助。经常使用的技巧就是为了避免图片过大而导致OOM,所以在我们载入图片之前就通过设置它为true,获取到图片的宽、高等值,然后进行一些推断检查等。决定图片是否压缩。我们来看看载入一张405x579图片的样例:
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResource(), R.mipmap.two, options);
Log.v("zxy","bitmap="+bitmap);
int height = options.outHeight;
int width = options.outWidth;
String mimeType = options.outMimeType;
Log.v("zxy","mimeType="+mimeType+",height="+height+",width="+width);
- 上述代码输出的是:能够知道确实是返回null了。并且还获得了该Bitmap的宽高等值。
2、通过实例来看看怎么压缩图片
public class MainActivity extends ActionBarActivity {
private ImageView mImageView, mResizeImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView);
mResizeImageView = (ImageView) findViewById(R.id.resize_imageView);
mImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.two));
Bitmap bitmap = compressBitmap(getResources(), R.mipmap.two, 100, 100);
Log.v("zxy", "compressBitmap,width=" + bitmap.getWidth() + ",height=" + bitmap.getHeight());
mResizeImageView.setImageBitmap(bitmap);
}
/**
* @param res Resource
* @param resId 资源id
* @param targetWidth 目标图片的宽,单位px
* @param targetHeight 目标图片的高,单位px
* @return 返回压缩后的图片的Bitmap
*/
public Bitmap compressBitmap(Resources res, int resId, int targetWidth, int targetHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//设为true,节约内存
BitmapFactory.decodeResource(res, resId, options);//返回null
int height = options.outHeight;//得到源图片height,单位px
int width = options.outWidth;//得到源图片的width。单位px
//计算inSampleSize
options.inSampleSize = calculateInSampleSize(width,height,targetWidth,targetHeight);
options.inJustDecodeBounds = false;//设为false,能够返回Bitmap
return BitmapFactory.decodeResource(res,resId,options);
}
/**
* 计算压缩比例
* @param width 源图片的宽
* @param height 源图片的高
* @param targetWidth 目标图片的宽
* @param targetHeight 目标图片的高
* @return inSampleSize 压缩比例
*/
public int calculateInSampleSize(int width,int height, int targetWidth, int targetHeight) {
int inSampleSize = 1;
if (height > targetHeight || width > targetWidth) {
//计算图片实际的宽高和目标图片宽高的比率
final int heightRate = Math.round((float) height / (float) targetHeight);
final int widthRate = Math.round((float) width / (float) targetWidth);
//选取最小的比率作为inSampleSize
inSampleSize = heightRate < widthRate ? heightRate : widthRate;
}
return inSampleSize;
}
}
我们通过看Log能够知道压缩后图片的宽高:
我们再看看效果图: