前言
Bitmap开发涉及到方方面面,比如裁剪图片,压缩图片,镜像图片,旋转图片,各种转存图片等等,是必需掌握Android开发技巧,Android开发提供了2个类来实现这些需求,Bitmap类与BitmapFactory类。此博客会持续更新各种实际需求。
将Res位图资源转成Bitmap
请注意,使用这个方法会出现Bitmap为null的问题。这个问题可能是因为资源id异常引起的。特别是你使用了分module形式构建的app
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
将指定文件转成Bitmap
Bitmap bitmap = BitmapFactory.decodeFile(getContext().getExternalCacheDir() + File.separator + "demo1.png");
将Drawable矢量图资源转成Bitmap
public static Bitmap getBitmapFromDrawable(Context context, @DrawableRes int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
} else if (drawable instanceof VectorDrawable || drawable instanceof VectorDrawableCompat) {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} else {
throw new IllegalArgumentException("unsupported drawable type");
}
}
将Uri转成Bitmap
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//相册选择图片
if (requestCode == GALLERY_RESULT_CODE && resultCode == RESULT_OK) {
final Uri uri = data.getData();
try (InputStream inputStream = getActivity().getApplicationContext().getContentResolver().openInputStream(uri)) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);//得到bitmap
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
}
将Bitmap输出成文件
Bitmap bitmap = BitmapFactory.decodeFile(getContext().getExternalCacheDir() + File.separator + "demo1.png");
File file = new File(getContext().getExternalCacheDir(), "demo.jpg");
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
//参数1:输出的图片格式 参数2:输出图片的压缩质量(范围值为0-100) 参数3:输出流
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
镜像垂直翻转
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Matrix matrix = new Matrix();
matrix.postScale(1, -1); //镜像垂直翻转
Bitmap changBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
镜像水平翻转
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Matrix matrix = new Matrix();
matrix.postScale(-1, 1); //镜像水平翻转
Bitmap changBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
mBinding.weatherIcon.setImageBitmap(changBitmap);
旋转图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Matrix matrix = new Matrix();
matrix.postRotate(-90); //旋转-90度
Bitmap changBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
mBinding.weatherIcon.setImageBitmap(changBitmap);
压缩图片质量,降低图片存储大小
原理其实很简单就是利用compress方法,一点一点的降低图片质量,最后压缩到需要的目标存储大小
/**
* 压缩图片
* @param bitmap bitmap图片 压缩
* @param targetKB 目标压缩大小
* @return
*/
private Bitmap compressImage(Bitmap bitmap, int targetKB){
Bitmap outBitmap = null;
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
int quality = 80;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
while ((baos.toByteArray().length/1024) > targetKB){
quality = quality-10;
baos.reset();
bitmap.compress(Bitmap.CompressFormat.JPEG,quality,baos);
}
bais = new ByteArrayInputStream(baos.toByteArray());
outBitmap = BitmapFactory.decodeStream(bais);
bais.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
onError(e);
} finally {
try {
bais.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return outBitmap;
}
压缩图片尺寸
原理是利用BitmapFactory.decodeStream方法,传入options,以降幂的方式等比例的压缩到目标尺寸,关键是options.inSampleSize = be;这个属性的配置
/**
* 尺寸压缩
* @param bitmap
*/
private Bitmap sizeCompres(Bitmap bitmap,float targetWidth,float targetHeight){
Bitmap handleBitmap = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,100,baos);
// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
if (baos.toByteArray().length / 1024 > 1024) {
baos.reset();// 重置baos即清空baos
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(bais,null,options);
options.inJustDecodeBounds = false;
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
int be = 1;
if (imageWidth>imageHeight && imageWidth>targetWidth){
be = Math.round(imageWidth/targetWidth);
}else if (imageHeight>imageWidth && imageHeight>targetHeight){
be = Math.round(imageHeight/targetHeight);
}
if (be <= 1){
be =1;//如果小于1等于1就不需要压缩直接返回
}
options.inSampleSize = be;
bais = new ByteArrayInputStream(baos.toByteArray());//bais运行到这里可能已经清空了,所以需要再次添加
handleBitmap = BitmapFactory.decodeStream(bais,null,options);
bais.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
return handleBitmap;
}
获取图片的角度属性与将图片角度属性设置回去
获取图片的角度属性很重要,这里说明下,因为我们在压缩或者读取图片成Bitmap后在保存到文件里会丢失图片的角度,这样下次在查看这张图片的时候极有可能是倒的图片
try {
ExifInterface exifInterface = new ExifInterface(inpPath);//获取图片角度
mDegrees = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
int angle = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
switch (angle){
case ExifInterface.ORIENTATION_ROTATE_270:
mDegrees = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
mDegrees = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
mDegrees = 90;
break;
default:
mDegrees = 0;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
将图片角度设置回去
Matrix matrix = new Matrix();
matrix.setRotate(mDegrees, bitmap.getWidth(), bitmap.getHeight());
Bitmap finishBitmap = Bitmap.createBitmap(finishBitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,true);
End
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/13566480.html
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
来源:https://www.cnblogs.com/guanxinjing/p/13566480.html |