Android(安卓)拍照 录音 拍视频 旋转 裁剪 压缩图片
16lz
2021-12-11
Android 6.0 动态权限参考 https://blog.csdn.net/qq_27400335/article/details/79412774Android 7.0 文件写入问题在AndroidManifest.xml 配置 FileProvider为了防止重复 android:authorities 一般配置为 包名.fileProvider 第二步res添加 xml文件夹,添加file_paths.xml 写入:<?xml version="1.0" encoding="utf-8"?> //调用册并裁减 //fileName 为全局变量(这里为了直观就没有写) String fileName = CameraUtils.photoAlbum(activity);----------------------------------------------------------//调用拍照并裁剪
String fileName = CameraUtils.photograph(activity);
------------------------------------------------------------------------------------
//调用拍视频
fileName = CameraUtils.shootVideo(activity);
--------------------------------------------------------------------------------------
//调用录音
CameraUtils.startRecord(new CameraUtils.RecordingCallBack() { @Override public void name(String name) { fileName = name; } @Override public void intent(Intent intent) { startActivityForResult(intent, CameraUtils.RECORD_FLAG); }});
--------------------------------------------------------------------------------------------
//回调
//裁剪后的图片uriprivate Uri cropUri;@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode==-1){ if (requestCode == CameraUtils.CAMERA_FLAG){ //相机 Uri uri= CameraUtils.compressCameraImg(mContext,fileName); if (uri!=null){ //如不需要裁剪 可不走这一步 cropUri=CameraUtils.crop(uri,this); } }else if (requestCode == CameraUtils.PHOTO_FLAG){ //相册 Uri uri = data.getData(); if (uri!=null){ //如不需要裁剪 可不走这一步 cropUri=CameraUtils.crop(uri,this); } }else if (requestCode == CameraUtils.CROP_FLAG){ //裁剪回调 if (cropUri!=null){ File file = null; try { file = new File(new URI(cropUri.toString())); ....... } catch (URISyntaxException e) { e.printStackTrace(); } }else { T.showShort(mContext,"裁剪失败"); } }else if (requestCode == CameraUtils.VIDEO_FLAG){ //视频回调 path 为视频地址 String path = CameraUtils.PRESERVE_PATH+"/" + fileName; if (!TextUtils.isEmpty(fileName)){ //视频资料 MediaMetadataRetriever media = new MediaMetadataRetriever(); media.setDataSource(path); //获取时长 单位秒 String duration = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); //旋转角度 String rotation = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); ........ } }else if (requestCode == CameraUtils.RECORD_FLAG) { //录音回调 uri 录音资源 Uri uri = data.getData(); String path = CameraUtils.PRESERVE_PATH+"/" + fileName; if (uri != null) { String temp = CameraUtils.getAudioFilePathFromUri(uri, getActivity()); boolean b = CameraUtils.saveVoiceToSD(temp); File file = new File(path); if (b && file.exists()) { //path 录音路径 ... } } }}
---------------------------------------------------------------------------------------------------------------------------------
//压缩图片(鲁班 Luban)
添加依赖:implementation 'top.zibin:Luban:1.1.3'Luban.with(this) .load(stringList)// 传人要压缩的图片列表 也可单张 .ignoreBy(100) // 忽略不压缩图片的大小 .setTargetDir("") // 设置压缩后文件存储位置 .setCompressListener(new OnCompressListener() { //设置回调 @Override public void onStart() { } @Override public void onSuccess(File file) { // TODO 压缩成功后调用,返回压缩后的图片文件 } @Override public void onError(Throwable e) { // TODO 当压缩过程出现问题时调用 } }).launch(); //启动压缩
-----------------工具类----------------------import android.app.Activity;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.graphics.Bitmap;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.MediaStore;import android.support.v4.content.FileProvider;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.UUID;/** * Created by Administrator on 2019/3/12 0012. */public class CameraUtils { //相机回调 public static int CAMERA_FLAG = 1; //视频回调 public static int VIDEO_FLAG = 2; //录音回调 public static int RECORD_FLAG = 3; //裁剪回调 public static int CROP_FLAG = 4; //相册回调 public static int PHOTO_FLAG = 3; private static String fileName; private static String mVoicePath; //裁剪后图片保存路径 private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg"; //文件保存路劲 private static final String PRESERVE_PATH = Environment.getExternalStorageDirectory() + "/宝宝印记"; //provider private static final String FILE_PROVIDER_NAME = "包名.fileProvider"; /** * 拍照 * @param activity * @return */ public static String photograph(Activity activity){ fileName=null; UUID uuid = UUID.randomUUID(); fileName = uuid + ".png"; //将拍摄的照片保存在一个指定好的文件下 File dir= new File(PRESERVE_PATH); if(!dir.exists()){ dir.mkdirs(); } File f = new File(dir, fileName); Uri u = Uri.fromFile(f); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //通过FileProvider创建一个content类型的Uri u = FileProvider.getUriForFile(activity, FILE_PROVIDER_NAME, f); } //调用系统相机 Intent intentCamera = new Intent(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //添加这一句表示对目标应用临时授权该Uri所代表的文件 intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE); //将拍照结果保存至photo_file的Uri中,不保留在相册中 intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, u); activity.startActivityForResult(intentCamera, CAMERA_FLAG); return fileName; } /** * 相册 * @param activity * @return */ public static String photoAlbum(Activity activity){ UUID uuid = UUID.randomUUID(); fileName = uuid + ".png"; Intent intent = new Intent(Intent.ACTION_PICK); //相片类型 intent.setType("image/*"); activity.startActivityForResult(intent, PHOTO_FLAG); return fileName; } /** * 裁剪 * @param uri */ public static Uri crop(Uri uri,Activity activity){ Uri imageUri = Uri.parse(IMAGE_FILE_LOCATION); Intent intent = new Intent("com.android.camera.action.CROP"); //图片资源uri intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); intent.putExtra("scale", true); //截图返回的uri intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); activity.startActivityForResult(intent, CROP_FLAG); return imageUri; } /** * 视频 * @param activity * @return */ public static String shootVideo(Activity activity){ fileName=null; UUID uuid = UUID.randomUUID(); fileName = uuid + ".mp4"; //将拍摄的照片保存在一个指定好的文件下 File dir= new File(PRESERVE_PATH); if(!dir.exists()){ dir.mkdirs(); } File f = new File(dir, fileName); Uri u = Uri.fromFile(f); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //通过FileProvider创建一个content类型的Uri u = FileProvider.getUriForFile(activity, FILE_PROVIDER_NAME, f); } //调用系统相机 Intent intentVideo = new Intent(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //添加这一句表示对目标应用临时授权该Uri所代表的文件 intentVideo.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } intentVideo.setAction(MediaStore.ACTION_VIDEO_CAPTURE); intentVideo.addCategory(Intent.CATEGORY_DEFAULT); //将拍照结果保存至photo_file的Uri中,不保留在相册中 intentVideo.putExtra(MediaStore.EXTRA_OUTPUT, u); activity.startActivityForResult(intentVideo, VIDEO_FLAG); return fileName; } /** * 启动录音机,创建文件 */ public static void startRecord(RecordingCallBack callBack) { UUID uuid = UUID.randomUUID(); fileName = uuid + ".amr"; //将拍摄的照片保存在一个指定好的文件下 File dir= new File(PRESERVE_PATH); if(!dir.exists()){ dir.mkdirs(); } callBack.name(fileName); File f = new File(dir, fileName); mVoicePath = f.getAbsolutePath(); f.setWritable(true); Intent intentRecord = new Intent(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //添加这一句表示对目标应用临时授权该Uri所代表的文件 intentRecord.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } intentRecord.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION); callBack.intent(intentRecord); } /** * 通过Uri,获取录音文件的路径(绝对路径) * * @param uri 录音文件的uri * @return 录音文件的路径(String) */ public static String getAudioFilePathFromUri(Uri uri,Activity activity) { Cursor cursor = activity.getContentResolver() .query(uri, null, null, null, null); cursor.moveToFirst(); int index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA); String temp = cursor.getString(index); cursor.close(); return temp; } /** * 保存音频到SD卡的指定位置 * * @param path 录音文件的路径 */ public static boolean saveVoiceToSD(String path) { boolean b = false; //创建输入输出 InputStream isFrom = null; OutputStream osTo = null; try { //设置输入输出流 isFrom = new FileInputStream(path); osTo = new FileOutputStream(mVoicePath); byte bt[] = new byte[1024]; int len; while ((len = isFrom.read(bt)) != -1) { osTo.write(bt, 0, len); } Log.d("TAG_Path", "保存录音完成。"); b=true; } catch (IOException e) { e.printStackTrace(); b=false; Log.d("TAG_Path", "e:"+e.toString()); } finally { if (osTo != null) { try { //不管是否出现异常,都要关闭流 osTo.close(); Log.d("TAG_Path", "关闭输出流"); } catch (IOException e) { e.printStackTrace(); b=false; } } if (isFrom != null) { try { isFrom.close(); Log.d("TAG_Path", "关闭输入流"); } catch (IOException e) { e.printStackTrace(); b=false; } } } return b; } public interface RecordingCallBack{ void name(String name); void intent(Intent intent); } public static Uri compressCameraImg(Context mContext,String fileName){ Uri imgUrl=null; if (fileName==null){ return null; } //返回原图 File fData = new File(PRESERVE_PATH+"/" + fileName); try { imgUrl = Uri.parse(MediaStore.Images.Media.insertImage(mContext.getContentResolver(), fData.getAbsolutePath(), null, null)); } catch (FileNotFoundException e) { e.printStackTrace(); } return imgUrl; } /** * android 转换 content://media/external/images/media/xxx * @param context * @param contentUri * @return */ public static String getRealPathFromUri(Context context, Uri contentUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } }
/** * 获取图片旋转角度 * 注意:获取图片旋转角度之前不能做任何操作(如:压缩、裁剪) * 注意:在高版本中 ExifInterface 会抛异常 * 解决方法:添加ExifInterface的依赖 implementation "com.android.support:exifinterface:27.1.1"(对应自己的SDK版本) * @param path 图片路径 * @return 图片旋转角度 */public static int readPictureDegree(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; default: break; } } catch (IOException e) { e.printStackTrace(); return degree; } return degree;}/** * 旋转图片 * @param degree 旋转角度 * @param bitmap 旋转图片 * @return */public static Bitmap rotaingImageView(int degree, Bitmap bitmap) { Matrix matrix = new Matrix(); matrix.postRotate(degree); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); return resizedBitmap;}/** * 旋转图片并保存到本地 * @param degree 旋转角度 * @param bitmap 旋转图片 * @return 返回图片路径 */public static String rotaingImageViewAndSave(Activity activity,int degree, Bitmap bitmap) { String path = null; Matrix matrix = new Matrix(); matrix.postRotate(degree); //设置图片缩放比例 长和宽放大缩小的比例 //matrix.postScale(0.5f,0.5f); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); if (resizedBitmap!=null){ //保存照片 path = saveBitmap(activity,resizedBitmap,""); } return path;}/** * 保存文件到相册,文件名为当前日期 * @param activity * @param bitmap 图片资源 * @param imageName 图片名称 * @return 返回图片路径 */public static String saveBitmap(Activity activity,Bitmap bitmap, String imageName){ String fileName ; File file =null; if(Build.BRAND .equals("Xiaomi") ){ fileName = Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"+imageName ; }else{ fileName = Environment.getExternalStorageDirectory().getPath()+"/DCIM/"+imageName ; } file = new File(fileName); if(file.exists()){ file.delete(); } FileOutputStream out; try{ out = new FileOutputStream(file); // 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中 if(bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)){ out.flush(); out.close(); // 插入图库 MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getAbsolutePath(), imageName, null); } } catch (IOException e) { e.printStackTrace(); } // 发送广播,通知刷新图库的显示 activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName))); if (file != null){ return file.getPath(); }else { return ""; }}}
更多相关文章
- android 设置桌面背景
- Android(安卓)Studio(十):添加assets目录
- Android(安卓)Studio(九):引用jar及so文件
- Android中imageView图片放大缩小及旋转功能示例代码
- android ndk Hello World
- Android读取xxx.properties配置文件中文出现乱码解决方法
- android studio 项目的版本问题
- android常用adb命令
- NPM 和webpack 的基础使用