我直接上代码,该有注释的地方都有,这一套基本满足小白的使用
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 作者:
*/
public class ImageUtils {
/**
* 保存图片到 SD card
*
* @param photoBitmap
* @param photoName
* @param path
*/
public static String savePhoto(Bitmap photoBitmap, String path,
String photoName) {
String localPath = null;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File photoFile = new File(path+"/"+photoName);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(photoFile);
if (photoBitmap != null) {
if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100,
fileOutputStream)) { // 转换完成
localPath = photoFile.getPath();
fileOutputStream.flush();
}
}
} catch (FileNotFoundException e) {
photoFile.delete();
localPath = null;
e.printStackTrace();
} catch (IOException e) {
photoFile.delete();
localPath = null;
e.printStackTrace();
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
fileOutputStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return localPath;
}
/**
* 转换图片成圆形
*
* @param bitmap 传入Bitmap对象
* @return
*/
public static Bitmap toRoundBitmap(Bitmap bitmap) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left,top,right,bottom,dst_left,dst_top,dst_right,dst_bottom;
if (width <= height) {
roundPx = width / 2;
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
Bitmap output = Bitmap.createBitmap(width,
height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int)left, (int)top, (int)right, (int)bottom);
final Rect dst = new Rect((int)dst_left, (int)dst_top, (int)dst_right, (int)dst_bottom);
final RectF rectF = new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
return output;
}
}
package com.jxd.whj_learn.utils.fileupload;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import com.jxd.whj_learn.base.CommenBaseActivity;
import com.jxd.whj_learn.base.CommenBaseFragment;
import com.jxd.whj_learn.utils.OSUtil;
import java.io.ByteArrayOutputStream;
import java.io.File;
/**
* @author wzq
* @data 2019/7/10
* @email [email protected]
* @for
*/
public class SelectphotoUtils {
protected static final int CHOOSE_PICTURE = 0;
protected static final int TAKE_PICTURE = 1;
protected static final int CROP_SMALL_PICTURE = 2;
//读写权限
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
//请求状态码
private static int REQUEST_PERMISSION_CODE = 101;
//图片路径
protected static Uri tempUri = null;
// /**
// * 显示选择头像来源对话框
// */
// @SuppressLint("ResourceAsColor")
// public static void showIconDialog(final BaseFragment ac, final Activity activity) {
// new MaterialDialog.Builder(activity)
// .title("选择图片来源")
// .titleGravity(GravityEnum.CENTER)
// .items(new String[]{"相册", "相机"})
// .positiveText("确定")
// .positiveColor(R.color.colorPrimary1)
// .widgetColorRes(R.color.colorPrimary1)//选中颜色
// .itemsCallbackSingleChoice(0, new MaterialDialog.ListCallbackSingleChoice() {
// @Override
// public boolean onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
// switch (which) {
// case CHOOSE_PICTURE: // 选择本地照片
// Intent openAlbumIntent = new Intent(Intent.ACTION_PICK,null);
// openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
// ac.startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);
// break;
// case TAKE_PICTURE: // 拍照
takePicture(activity);
// break;
// }
// dialog.dismiss();
// return false;
// }
// }).show();
//
// }
/**
* 拍照(fragment中调用此方法)
*/
public static void takePicture(Context context, CommenBaseFragment baseFragment, File file) {
if (ContextCompat.checkSelfPermission(baseFragment.getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// 进入这儿表示没有权限
if (ActivityCompat.shouldShowRequestPermissionRationale(baseFragment.getActivity(), Manifest.permission.CAMERA)) {
// 提示已经禁止
// ToastUtil.longToast(mContext, getString(R.string.you_have_cut_down_the_permission));
} else {
ActivityCompat.requestPermissions(baseFragment.getActivity(), new String[]{Manifest.permission.CAMERA}, 100);
}
} else {
//获取存储权限
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(baseFragment.getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(baseFragment.getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// 提示已经禁止
} else {
ActivityCompat.requestPermissions(baseFragment.getActivity(), PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(baseFragment.getActivity().getPackageManager()) != null) {
Uri fileUri = FileProvider7.getUriForFile(baseFragment.getActivity(), file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
baseFragment.getActivity().startActivityForResult(takePictureIntent, TAKE_PICTURE);
}
}
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(baseFragment.getActivity().getPackageManager()) != null) {
Uri fileUri = FileProvider7.getUriForFile(baseFragment.getActivity(), file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
baseFragment.getActivity().startActivityForResult(takePictureIntent, TAKE_PICTURE);
}
}
}
}
/**
* 拍照(Activity中调用此方法)
*/
public static void takePicture1(CommenBaseActivity baseActivity, File file) {
if (ContextCompat.checkSelfPermission(baseActivity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// 进入这儿表示没有权限
if (ActivityCompat.shouldShowRequestPermissionRationale(baseActivity, Manifest.permission.CAMERA)) {
// 提示已经禁止
// ToastUtil.longToast(mContext, getString(R.string.you_have_cut_down_the_permission));
} else {
ActivityCompat.requestPermissions(baseActivity, new String[]{Manifest.permission.CAMERA}, 100);
}
} else {
//获取存储权限
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(baseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(baseActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// 提示已经禁止
} else {
ActivityCompat.requestPermissions(baseActivity, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(baseActivity.getPackageManager()) != null) {
Uri fileUri = FileProvider7.getUriForFile(baseActivity, file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
baseActivity.startActivityForResult(takePictureIntent, TAKE_PICTURE);
}
}
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(baseActivity.getPackageManager()) != null) {
Uri fileUri = FileProvider7.getUriForFile(baseActivity, file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
baseActivity.startActivityForResult(takePictureIntent, TAKE_PICTURE);
}
}
}
}
/**
* 裁剪图片方法实现(fragment中调用此方法)
*
* @param uri
*/
public static void startPhotoZoom(Uri uri, final CommenBaseFragment activity, File file) {
if (uri == null) {
Log.i("tag", "The uri is not exist.");
}
tempUri = uri;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
//sdk>=24
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.putExtra("noFaceDetection", false);//去除默认的人脸识别,否则和剪裁匡重叠
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
if (android.os.Build.MANUFACTURER.equals("HUAWEI")) {//华为手机的裁剪框为圆形,需要如下判断
intent.putExtra("aspectX", 9998);
intent.putExtra("aspectY", 9999);
}else {
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
}
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
// intent.putExtra("return-data", true);
// activity.startActivityForResult(intent, CROP_SMALL_PICTURE);
Log.e("1111111111111111", "startPhotoZoom: " + file);
Log.e("1111111111111111", "startPhotoZoom: " + Environment.getExternalStorageDirectory().getPath() + "/" + "whj_hand.jpg");
if (OSUtil.isMIUI()) {
Uri uritempFile = Uri.parse("file://" + "/" + file);
// Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg"
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
} else {
intent.putExtra("return-data", true);
}
activity.startActivityForResult(intent, CROP_SMALL_PICTURE);
}
/**
* 裁剪图片方法实现(Activity中调用此方法)
*
* @param uri
*/
public static void startPhotoZoom1(Uri uri, final CommenBaseActivity activity, File file) {
if (uri == null) {
Log.i("tag", "The uri is not exist.");
}
tempUri = uri;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
//sdk>=24
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.putExtra("noFaceDetection", false);//去除默认的人脸识别,否则和剪裁匡重叠
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
if (android.os.Build.MANUFACTURER.equals("HUAWEI")) {//华为手机的裁剪框为圆形,需要如下判断
intent.putExtra("aspectX", 9998);
intent.putExtra("aspectY", 9999);
}else {
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
}
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
if (OSUtil.isMIUI()) {
Uri uritempFile = Uri.parse("file://" + "/" + file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
} else {
intent.putExtra("return-data", true);
}
activity.startActivityForResult(intent, CROP_SMALL_PICTURE);
}
/**
* 定义方法判断SD卡的存在性
*/
public static boolean isExistSd() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return true;
} else
return false;
}
/**
* 获取SD可用容量
*/
private static long getAvailableStorage(Context context) {
String root = context.getExternalFilesDir(null).getPath();
StatFs statFs = new StatFs(root);
long blockSize = statFs.getBlockSize();
long availableBlocks = statFs.getAvailableBlocks();
long availableSize = blockSize * availableBlocks;
// Formatter.formatFileSize(context, availableSize);
return availableSize;
}
/**
* 采样率压缩图片
*/
public static Bitmap getBitmap(Bitmap bitmap, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bytes = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
Log.i("info", "图片大小:" + bit.getByteCount());//2665296 10661184
return bit;
}
}
package com.jxd.whj_learn.utils.fileupload;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import java.io.File;
/**
* @author wzq
* @data 2020/3/4
* @email [email protected]
* @for 7.0版本兼容性辅助类
*/
public class FileProvider7 {
public static Uri getUriForFile(Context context, File file) {
Uri fileUri = null;
if (Build.VERSION.SDK_INT >= 24) {
fileUri = getUriForFile24(context, file);
} else {
fileUri = Uri.fromFile(file);
}
return fileUri;
}
public static Uri getUriForFile24(Context context, File file) {
Uri fileUri = android.support.v4.content.FileProvider.getUriForFile(context,
context.getPackageName() + ".android7.fileprovider",//(这里报空的话直接使用包名xxx.com.xx.android7.fileprovider)
file);
return fileUri;
}
public static void setIntentDataAndType(Context context,
Intent intent,
String type,
File file,
boolean writeAble) {
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(getUriForFile(context, file), type);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (writeAble) {
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
} else {
intent.setDataAndType(Uri.fromFile(file), type);
}
}
}
工具类中方法有重复部分是在活动Activity中和fragment中的区别,因为涉及到相机的回调启动
还涉及到了一个provider的创建 在res下创建一个xml包 新建file_path.xml文件
```java
还需要在mainfessts中声明一下
```java
备注:
mainfests中记得申明需要的拍照权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
最后就是在Activity中/fragment中调用方法使用就行了
我简单的来个例子吧 以Activity中为例:
先声明几个变量为了在回调中跟工具类中调用startActivityForResult传过来的值匹配
protected static final int CHOOSE_PICTURE = 0;
protected static final int TAKE_PICTURE = 1;
protected static final int CROP_SMALL_PICTURE = 2;
//图片路径
protected static Uri tempUri = null;
private File selectFile ;
·············
/**
* 显示选择头像来源对话框
*/
@SuppressLint("ResourceAsColor")
public static void showIconDialog() {
new MaterialDialog.Builder(xxActivity.this)
.title("选择图片来源")
.titleGravity(GravityEnum.CENTER)
.items(new String[]{"相册", "相机"})
.positiveText("确定")
.positiveColor(R.color.colorPrimary1)
.widgetColorRes(R.color.colorPrimary1)//选中颜色
.itemsCallbackSingleChoice(0, new MaterialDialog.ListCallbackSingleChoice() {
@Override
public boolean onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
switch (which) {
case CHOOSE_PICTURE: // 选择本地照片
Intent openAlbumIntent = new Intent(Intent.ACTION_PICK, null);
openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);
dialogView1.dismiss();
break;
case TAKE_PICTURE: // 拍照
selectFile = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+"jz_app.jpg");
SelectphotoUtils.takePicture(xxxActivity.this, selectFile);
break;
}
dialog.dismiss();
return false;
}
}).show();
}
/**
* 监听Activity返回值
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case CHOOSE_PICTURE:// 直接从相册获取
try {
SelectphotoUtils.startPhotoZoom1(data.getData(),AccountActivity.this);
} catch (NullPointerException e) {
e.printStackTrace();// 用户点击取消操作
}
break;
case TAKE_PICTURE:// 调用相机拍照
if (isExistSd()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//如果是7.0剪裁图片 同理 需要把uri包装
Uri fileUri = FileProvider7.getUriForFile(MineInfoActivity.this, selectFile );
if (selectFile .exists()) {
//对相机拍照照片进行裁剪
SelectphotoUtils.startPhotoZoom1(fileUri, MineInfoActivity.this, selectFile );
}
} else {
if (selectFile .exists()) {
//对相机拍照照片进行裁剪
SelectphotoUtils.startPhotoZoom1(Uri.fromFile(file), MineInfoActivity.this, selectFile );
}
}
} else {
Toast.makeText(MineInfoActivity.this, "图片保存失败", Toast.LENGTH_SHORT).show();
}
break;
case CROP_SMALL_PICTURE://取得裁剪后的图片
if (data != null) {
setPicToView(data);
}
break;
}
}
/**
* 保存裁剪之后的图片数据
*
* @param data
*/
protected void setPicToView(Intent data) {
Bundle extras = data.getExtras();
Bitmap bitmap = null;
try {
if (OSUtil.isMIUI()) {
Uri uritempFile = Uri.parse("file://" + "/" + selectFile);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
if (extras != null) {
bitmap = extras.getParcelable("data");
}
}
//获得图片路径
filepath = UploadImage.saveFile(bitmap, Environment.getExternalStorageDirectory().toString(), "hand.jpg");
uploadPic(bitmap);
} catch (Exception e) {
}
}
/**
* 保存头像并上传服务器
*
* @param bitmap
*/
private void uploadPic(final Bitmap bitmap) {
// 上传至服务器
//这里具体上传到是什么地方以什么形式上传就根据你自己的需要写就好了 ,请求接口你肯定也有自己的一套方法,具体是以file上传还是Base64都行
// 我就简单附上一个Bmob后端云的上传例子吧
String imagename = currentUser.getObjectId() + "_" + String.valueOf(System.currentTimeMillis());
String imagePath = ImageUtils.savePhoto(bitmap, Environment
.getExternalStorageDirectory().getAbsolutePath(), imagename + ".png");
if (imagePath != null) {
final BmobFile bmobFile = new BmobFile(new File(imagePath));
bmobFile.uploadblock(new UploadFileListener() {
@Override
public void done(BmobException e) {
if (e==null) {
MyUser newUser=new MyUser();
newUser.setImage(bmobFile.getFileUrl());
newUser.update(currentUser.getObjectId(),new UpdateListener() {
@Override
public void done(BmobException e) {
if (e==null) {
Toast.makeText(getActivity(), "上传成功", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getActivity(), "上传失败", Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(getActivity(), "上传失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
很多代码都是参考网上的资料自己简单的做了总结和整理,如过侵权请联系我删除,谢谢!