本文出自 “阿敏其人” 简书博客,转载或引用请注明出处。
我们要做的是从类似qq更换头像的功能。按下头像,弹出popup,通过拍照或者从相册选择图片,缩放,选择合适的大小,然后点击完成,更新头像。
一、先来简单地加载一张图片

最简单的代码:
xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity"
android:background="#ffffff"
>
<ImageView
android:id="@+id/mIvPic"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:src="@mipmap/def_pic"
/>
</RelativeLayout>
.
.
MainActivity
public class MainActivity extends Activity {
private ImageView mIvPic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIvPic = (ImageView) findViewById(R.id.mIvPic);
}
}

.
.
一、1 假如我们觉得矩形有点丑,想弄成圆角矩形怎么办呢?
我们知道,不管程序自带的图片,还是相册的图片,全部都是Bitmap。
既然要改变,我们就需要从Bitmap着手。
我们新建一个ImageTools类,添加一个方法,用于输出圆角(或者圆形)的bitmap
*/
public class ImageTools {
/**
*
* 创建圆角图片
* @param x 图像的宽度
* @param y 图像的高度
* @param image 源图片
* @param outerRadiusRat 圆角的大小
* @return 圆角图片
*/
public static Bitmap createFramedPhoto(int x, int y, Bitmap image, float outerRadiusRat) {
//根据源文件新建一个darwable对象
Drawable imageDrawable = new BitmapDrawable(image);
// 新建一个新的输出图片
Bitmap output = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
// 新建一个矩形
RectF outerRect = new RectF(0, 0, x, y);
// 产生一个红色的圆角矩形
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
// 利用画笔画出一个矩形,第二个参数和第三个参数就是我们方法的传进来的圆角角度
canvas.drawRoundRect(outerRect, outerRadiusRat, outerRadiusRat, paint);
// 将源图片绘制到这个圆角矩形上
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
imageDrawable.setBounds(0, 0, x, y);
canvas.saveLayer(outerRect, paint, Canvas.ALL_SAVE_FLAG);
imageDrawable.draw(canvas);
canvas.restore();
return output;
}
}
.
.
然后在MainActivity里添加两行代码
public class MainActivity extends Activity {
private ImageView mIvPic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIvPic = (ImageView) findViewById(R.id.mIvPic);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.def_pic);
mIvPic.setImageBitmap(ImageTools.createFramedPhoto(80, 80, bitmap, 10));
}
}
简单的圆角矩形呼之即出

关于BitMmap的相关知识可以大概此文 安卓OOM和Bitmap图片二级缓存机制(一)
上面说了这么多,跟相册和头像没有毛线关系。那么现在,开始一点点关于相册和拍照的。
二、弹出Popup,选择相册或者拍照
思路是这样子:
点击图片的时候,我们弹出popupWindow,popup有三个选项
“拍照”
“相册”
“取消”
点击“拍照”和“相册”的时候,利用Intent调用系统的拍照和相册,使用
startActivityForResult的方式,传入一个请求码。
随后,在系统的onActivityResult方法里面针对不同的请求码做不同的操作。
开动:
既然要需要popup,首先就需要一个pop的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:background="@drawable/shape_bg_pop"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true"
>
<TextView
android:id="@+id/mTvPhoto"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:background="@drawable/selector_pop_item"
android:gravity="center"
android:text="拍照"
android:textColor="#0479FE"
android:textSize="18sp" />
<TextView
android:id="@+id/mTvAlbum"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_above="@+id/cancel"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:background="@drawable/selector_pop_item"
android:gravity="center"
android:text="从相册选择"
android:textColor="#0479FE"
android:layout_centerInParent="true"
android:textSize="18sp"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="10dp"
android:background="@drawable/selector_pop_item"
android:gravity="center"
android:text="取 消"
android:textColor="#0479FE"
android:textSize="18sp"
>
</TextView>
</LinearLayout>
</RelativeLayout>

关于PopupWindow的学习可以参考这里:android的PopupWindow简解
接下来可以正式写代码了
public class MainActivity extends Activity {
private ImageView mIvPic;
private PopupWindow popWindow;
private LayoutInflater layoutInflater;
private TextView mTvPhoto, mTvAlbum;
private TextView cancel;
public static final int PHOTOALBUMS = 0; // 相册
public static final int PHOTOTAKE = 1; // 拍照
public static final int IMAGE_COMPLETE = 2; // 结果
private String photoSavePath;//保存文件夹路径
private String photoSaveName;// 图片名称
private String picFullPath;//图片全路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// 创建存放图片的文件夹
File file = new File(Environment.getExternalStorageDirectory(), "ChoosePic/cache");
SdCradUtils.createSDPath(file);
// 这句代码不能少,因为我们的pop的点击事件有用到。
photoSavePath=Environment.getExternalStorageDire
ctory()+"/ChoosePic/cache/";
// 定义图片文件名
photoSaveName =System.currentTimeMillis()+ ".png";
mIvPic = (ImageView) findViewById(R.id.mIvPic);
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.def_pic);
// mIvPic.setImageBitmap(ImageTools.createFramedPhoto(80, 80, bitmap, 10));
mIvPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPopupWindow(mIvPic);
}
});
}
// 弹出Popup
private void showPopupWindow(View parent){
if (popWindow == null) {
View view = layoutInflater.inflate(R.layout.pop_select_photo,null);
popWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,true);
initPop(view);
}
popWindow.setAnimationStyle(android.R.style.Animation_Toast);
popWindow.setFocusable(true);
popWindow.setOutsideTouchable(true);
popWindow.setBackgroundDrawable(new BitmapDrawable());
popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popWindow.showAtLocation(parent, Gravity.CENTER, 0, 0);
}
// 初始化pop,对pop的选项进行操作
public void initPop(View view){
mTvPhoto = (TextView) view.findViewById(R.id.mTvPhoto);//拍照
mTvAlbum = (TextView) view.findViewById(R.id.mTvAlbum);//相册
cancel = (TextView) view.findViewById(R.id.cancel);//取消
// 点击拍照
mTvPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
// 拍照后的图片的名字
photoSaveName = String.valueOf(System.currentTimeMillis()) + ".png";
Uri imageUri = null;
// 调用系统相机
Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 指定拍照后图片的存放路径和名称
imageUri = Uri.fromFile(new File(photoSavePath, photoSaveName));
openCameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// 启动系统相机,Intent的请求码为PHOTOTAKE,用于在onActivityResult方法里面做相应操作
startActivityForResult(openCameraIntent, PHOTOTAKE);
}
});
// 点击相册
mTvAlbum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
// 4.4以上成功返回相册路径,并且向下兼容
Intent openAlbumIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(openAlbumIntent, PHOTOALBUMS);
}
});
// 点击取消
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
}
});
}
@SuppressWarnings("deprecation")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = null;
switch (requestCode) {
case PHOTOTAKE://拍照
picFullPath=photoSavePath+photoSaveName;
uri = Uri.fromFile(new File(picFullPath));
System.out.println("拍照后得到的图片路径"+picFullPath);
//简单粗暴地显示图片 (不好)
Bitmap bitmap = BitmapFactory.decodeFile(picFullPath);
mIvPic.setImageBitmap(bitmap);
break;
case PHOTOALBUMS://相册
uri = data.getData();
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, proj, null, null,null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
picFullPath = cursor.getString(column_index);// 图片在的路径
//简单粗暴地显示图片 (不好)
Bitmap bitmapAlbum = BitmapFactory.decodeFile(picFullPath);
mIvPic.setImageBitmap(bitmapAlbum);
System.out.println("调用相册后得到图片路径"+picFullPath);
Log.d("qwe","xxxxxxxxx");
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
.
.
代码中我们还涉及到一个SD卡工具类
public class SdCradUtils {
/**
* 判断SDCard是否可用
*
* @return
*/
public static boolean isSDCardEnable() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
/**
* 根据传进来的File创建文件夹
* 如果不存在,那么就创建
* 如果已经存在该文件夹,那么不做任何操作(不会覆盖已存在的文件夹,不会影响旧文件夹已有的数据)
* @param file
*/
public static void createSDPath(File file) { //根据传来的路径创建sd卡
if (isSDCardEnable()) {// 如果存在这个可以用的sd卡
if (!file.exists()){
file.mkdirs();
}
}
}
}
在上面的代码中,我们在onCreate里面先创建了一个文件夹,即将拍照将另存在指定地址的图片指定了名称。
点击图片,弹出popup,相应的打开系统相机和相册几乎是模板代码。
最后,在onActivityResult里面根据请求码的不同,做相应的操作。
需要注意的是,按照我们上面的方式,我们拍照是以原图的方式存储到我们知道的位置,现在的手机像素都非常好,分辨率特别大,一般都是数千乘数千的的分辨率。这样不行,容易导致OOM.
所以像上面的代码虽然把大致的效果给弄出来了,但是这样要是在开发中绝对是不允许的。
所以接下来我们要对onActivityResult里面的代码进行完善:
拍照:得到原始的图片后,对图片进行压缩另存到我们知道的文件夹下,指定缩减至200k以下,然后加载压缩后的图片
相册:将相册选择好的图片压缩到200k以下(不动相册原有的图片),另存到我们指定的路径下,加载压缩后的图片
这里我们用到了两个工具类的方法:
关于压缩的:
/**
* 先按宽高比例大小缩小,再压缩为指定大小以下
* 针对的是File
* @param srcPath 图片路径
* @param targetWidth 目标宽度
* @param targetHeight 目标高度
* @param targetKbSize 多少kb以下
* @return
*/
public static Bitmap decodeAndCompress(String srcPath,float targetWidth, float targetHeight,int targetKbSize) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设为true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int startW= newOpts.outWidth;
int startH = newOpts.outHeight;
float targetH = targetHeight;//这里设置目标高度
float targetW = targetWidth;//这里设置目标宽度
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int squareRate = 1;//be=1表示不缩放,squareRate只能是整数大于1的整数,如果是2表示四分之一
if (startW > startH && startW > targetW) {//如果宽度大的话根据宽度固定大小缩放
squareRate = (int) (newOpts.outWidth / targetW);
} else if (startW < startH && startH > targetH) {//如果高度高的话根据宽度固定大小缩放
squareRate = (int) (newOpts.outHeight / targetH);
}
if (squareRate <= 0){
squareRate = 1;
}
newOpts.inSampleSize = squareRate;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressQuality(bitmap,targetKbSize);//压缩好比例大小后再进行质量压缩
}
/**
* 先让图片缩放到多少内存以下,接着缩放,最后压缩
* 针对的是bitmap
* 此方法对比decodeAndCompress最大的好处就是针对特别大的图片,一开始就先把大小限制在指定范围以下
* @param image bitmap
* @param maxSize 界限,多少kb以下
* @param targetWidth 目标宽
* @param targetHeight 目标高
* @param targetKbSize 最终压缩到多少kb以下
* @return
*/
public static Bitmap compressLimitDecodeCompress(Bitmap image,int maxSize,float targetWidth, float targetHeight,int targetKbSize) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if( (baos.toByteArray().length / 1024)>maxSize) {//判断如果图片大于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 startW = newOpts.outWidth;
int startH = newOpts.outHeight;
float targetW = targetWidth;
float targetH = targetHeight;
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (startW > startH && startW > targetH) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / targetH);
} else if (startW < startH && startH > targetW) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / targetW);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;//设置缩放比例
newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressQuality(bitmap,targetKbSize);//压缩好比例大小后再进行质量压缩
}
/**
* 压缩图片质量到指定大小以下
* @param bitmap
* @param targetKbSize
* @return
*/
private static Bitmap compressQuality(Bitmap bitmap, int targetKbSize) {
// 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
// 将字节换成KB
double mid = b.length / 1024;
// 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
if (mid > targetKbSize) {
// 获取bitmap大小 是允许最大大小的多少倍
double i = mid / targetKbSize;
// 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
bitmap = zoomImage(bitmap, bitmap.getWidth() / Math.sqrt(i),
bitmap.getHeight() / Math.sqrt(i));
}
return bitmap;
}
public static Bitmap zoomImage(Bitmap bgimage, double newWidth, double newHeight) {
// 获取这个图片的宽和高
float width = bgimage.getWidth();
float height = bgimage.getHeight();
// 创建操作图片用的matrix对象
Matrix matrix = new Matrix();
// 计算宽高缩放率
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 缩放图片动作
matrix.postScale(scaleWidth, scaleHeight);
Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
(int) height, matrix, true);
return bitmap;
}
.
.
关于将Bitmap另存到sd卡的
/**
* 保存图片到sd卡片 亲测
* @param mBitmap
* @param path
* @param picName
*/
public static void saveBitmapToSdCard(Bitmap mBitmap,String path,String picName) {
File f = new File(path+picName + ".jpg");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
.
.
附上完整代码,主要看onActivityResult
public class MainActivity extends Activity {
private ImageView mIvPic;
private PopupWindow popWindow;
private LayoutInflater layoutInflater;
private TextView mTvPhoto, mTvAlbum;
private TextView cancel;
public static final int PHOTOALBUMS = 0; // 相册
public static final int PHOTOTAKE = 1; // 拍照
public static final int IMAGE_COMPLETE = 2; // 结果
private String photoSavePath;//保存文件夹路径
private String photoSaveName;// 图片名称
private String picFullPath;//图片全路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// 创建存放图片的文件夹
File file = new File(Environment.getExternalStorageDirectory(), "ChoosePic/cache");
SdCradUtils.createSDPath(file);
// 这句代码不能少,因为我们的pop的点击事件有用到。
photoSavePath=Environment.getExternalStorageDirectory()+"/ChoosePic/cache/";
// 定义图片文件名
photoSaveName =System.currentTimeMillis()+ ".png";
mIvPic = (ImageView) findViewById(R.id.mIvPic);
// Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.def_pic);
// mIvPic.setImageBitmap(ImageTools.createFramedPhoto(80, 80, bitmap, 10));
mIvPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPopupWindow(mIvPic);
}
});
}
// 弹出Popup
private void showPopupWindow(View parent){
if (popWindow == null) {
View view = layoutInflater.inflate(R.layout.pop_select_photo,null);
popWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,true);
initPop(view);
}
popWindow.setAnimationStyle(android.R.style.Animation_Toast);
popWindow.setFocusable(true);
popWindow.setOutsideTouchable(true);
popWindow.setBackgroundDrawable(new BitmapDrawable());
popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popWindow.showAtLocation(parent, Gravity.CENTER, 0, 0);
}
// 初始化pop,对pop的选项进行操作
public void initPop(View view){
mTvPhoto = (TextView) view.findViewById(R.id.mTvPhoto);//拍照
mTvAlbum = (TextView) view.findViewById(R.id.mTvAlbum);//相册
cancel = (TextView) view.findViewById(R.id.cancel);//取消
// 点击拍照
mTvPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
// 拍照后的图片的名字
photoSaveName = String.valueOf(System.currentTimeMillis()) + ".png";
Uri imageUri = null;
// 调用系统相机
Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 指定拍照后图片的存放路径和名称
imageUri = Uri.fromFile(new File(photoSavePath, photoSaveName));
openCameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// 启动系统相机,Intent的请求码为PHOTOTAKE,用于在onActivityResult方法里面做相应操作
startActivityForResult(openCameraIntent, PHOTOTAKE);
}
});
// 点击相册
mTvAlbum.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
// 4.4以上成功返回相册路径,并且向下兼容
Intent openAlbumIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(openAlbumIntent, PHOTOALBUMS);
}
});
// 点击取消
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
}
});
}
@SuppressWarnings("deprecation")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = null;
switch (requestCode) {
case PHOTOTAKE://拍照
picFullPath=photoSavePath+photoSaveName;
uri = Uri.fromFile(new File(picFullPath));
System.out.println("拍照后得到的图片路径"+picFullPath);
//简单粗暴地显示图片 (不好)
Bitmap bitmap = BitmapFactory.decodeFile(picFullPath);
// 首先让图片变成1m以下,接着按照300*300的宽高去压缩,接着指定大小不超过200kb
Bitmap bitmapCompress = CompressImageUtils.compressLimitDecodeCompress(bitmap, 1024, 300f, 300f, 200);
ImageTools.saveBitmapToSdCard(bitmapCompress, photoSavePath, FileUtils.getFileName(picFullPath) + "compress");
//SdCradUtils.deleteFile(picFullPath); //压缩之后删除照片
mIvPic.setImageBitmap(bitmap);
break;
case PHOTOALBUMS://相册
uri = data.getData();
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, proj, null, null,null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
picFullPath = cursor.getString(column_index);// 图片在的路径
//简单粗暴地显示图片 (不好)
FileUtils.getFileOrFilesSize(picFullPath, 2); // 压缩前的图片大小
Bitmap bitmapAlbum = BitmapFactory.decodeFile(picFullPath);
// 首先让图片变成1m以下,接着按照300*300的宽高去压缩,接着指定大小不超过200kb
Bitmap bmCompress = CompressImageUtils.compressLimitDecodeCompress(bitmapAlbum, 1024, 300f, 300f, 200);
ImageTools.saveBitmapToSdCard(bmCompress, photoSavePath, FileUtils.getFileName(picFullPath) + "alb_compress");
mIvPic.setImageBitmap(bmCompress);
System.out.println("调用相册后得到图片路径" + picFullPath);
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
实测之后我们发现,原本好几M的图片确实被压缩到200k以下了。

提示:为了防止拍照后旋转手机,点击确定无法返回的问题
可以在清单文件的对应activity的添加
android:configChanges="orientation|keyboardHidden"
(屏幕横向纵向切换的问题)
展示图:

本篇完。
网友评论