赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
最近在写一个人脸识别的小练习,现在记录一下
从手机照片获取一张人脸照片,进行检测,调用百度ai人脸检测接口。
代码如下(示例):
implementation 'com.orhanobut:hawk:2.0.1'//数据存储
//图片加载框架
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.12'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1")
implementation("androidx.fragment:fragment-ktx:1.4.1")
项目包名如图所示:
在application中添加一个类名为MyApplication的类
public class MyApplication extends Application { static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); Hawk.init(this).build(); //初始化 NetworkApi.init(new NetworkRequiredInfo(this)); } public static synchronized MyApplication context() { return (MyApplication) context; } /** *Show Toast 简单封装 */ public static void showToastLong(String msg) { showToast(context, msg, Toast.LENGTH_LONG); } public static void showToastShort(String msg) { showToast(context, msg, Toast.LENGTH_SHORT); } public static void showToastShort(int strRes) { showToast(context, context.getString(strRes), Toast.LENGTH_SHORT); } public static void showToast(String msg) { showToast(context, msg, Toast.LENGTH_SHORT); } public static void showToast(int strRes) { showToast(context, context.getString(strRes), Toast.LENGTH_SHORT); } public static void showToastLong(int strRes) { showToast(context, context.getString(strRes), Toast.LENGTH_LONG); } public static void showToast(Context context, String msg, int duration) { Toast.makeText(context, msg, duration).show(); } }
在application中添加一个类名为NetworkRequiredInfo 的类
public class NetworkRequiredInfo implements INetworkRequiredInfo { private Application application; public NetworkRequiredInfo(Application application){ this.application = application; } /** * 版本名 */ @Override public String getAppVersionName() { return "1"; } /** * 版本号 */ @Override public String getAppVersionCode() { return "1.0"; } /** * 是否为debug */ @Override public boolean isDebug() { return BuildConfig.DEBUG; } /** * 应用全局上下文 */ @Override public Application getApplicationContext() { return application; } }
在application中添加一个类名为AppContext的类
public class AppContext extends MyApplication { private static AppContext instance; @Override public void onCreate() { super.onCreate(); instance = this; } /** * 获得当前app运行的AppContext */ public static AppContext getInstance() { return instance; } /** * ResponseBody 处理成 Json */ public static String doJson(ResponseBody responseBody) { long contentLength = responseBody.contentLength(); BufferedSource source = responseBody.source(); try { source.request(Long.MAX_VALUE); // Buffer the entire body. } catch (IOException e) { e.printStackTrace(); } Buffer buffer = source.buffer(); Charset charset = UTF8; MediaType contentType = responseBody.contentType(); if (contentType != null) { try { charset = contentType.charset(UTF8); } catch (UnsupportedCharsetException e) { e.printStackTrace(); } } String result = ""; // 拦截器, if (contentLength != 0) { result = buffer.clone().readString(charset); // Log.e("MainActivity", " doJson====>:" + result); } return result; } private static final Charset UTF8 = Charset.forName("UTF-8"); /*** * 将指定路径的图片转uri * @param context * @param path ,指定图片(或文件)的路径 * @return */ @SuppressLint("Range") public static Uri getMediaUriFromPath(Context context, String path) { Uri mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; Cursor cursor = context.getContentResolver().query(mediaUri, null, MediaStore.Images.Media.DISPLAY_NAME + "= ?", new String[] { path.substring(path.lastIndexOf("/") + 1) }, null); Uri uri = null; if (cursor.moveToFirst()) { uri = ContentUris.withAppendedId(mediaUri, cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID))); } cursor.close(); return uri; } /** * 将相册uri转换成url */ public static String getRealPathFromURI(Context context, Uri contentURI) { String result; Cursor cursor = context.getContentResolver().query(contentURI, new String[] { MediaStore.Images.ImageColumns.DATA },// null, null, null); if (cursor == null) { result = contentURI.getPath(); } else { cursor.moveToFirst(); int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); result = cursor.getString(index); cursor.close(); } return result; } /** * 将拍照的图片保存到系统相册 */ public static String saveImageToGallery(Context context, Bitmap bmp) { String fileName = "zhengfutanfang" + ".jpg"; //检查有没有存储权限 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { AppContext.showToast("请至权限中心打开应用权限"); return "saveError"; } else { // 新建目录appDir,并把图片存到其下 File appDir = new File(context.getExternalFilesDir(null).getPath() + "BarcodeBitmap"); if (!appDir.exists()) { appDir.mkdir(); } File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 把file里面的图片插入到系统相册中 try { MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 通知相册更新 context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file))); return context.getExternalFilesDir(null).getPath() + "BarcodeBitmap/" + fileName; } } }
在service包中添加一个ApiService接口类
public interface ApiService { public static String mBaseUrl = "http://10.0.2.2:8080/web-lesson3-demo/"; //获取验证码 @GET("api/validate-code") Observable<CodeBean> getCodePicture(); @GET("api/validate-code") Observable<ResponseBody> getCodePicture2(); //登录接口 @POST("api/login") Observable<ResponseBody> loginApi(@Body RequestBody body); //识别脸部照片 @POST("api/ai-face") @Multipart Observable<ResponseBody> uploadFacePhoto2(@Part MultipartBody.Part part, @Part("token") RequestBody token); //识别脸部照片 @POST("api/ai-face") @Multipart Observable<FaceBean> uploadFacePhoto(@Part MultipartBody.Part part, @Part("token") RequestBody token); }
public class FaceDetectionActivity extends BaseActivity<ActivityFaceDetectionBinding> { private static final int REQUEST_CODE = 10000;//权限 private static final int TAKE_PHOTO = 11;// 拍照 private static final int LOCAL_CROP = 13;// 本地图库 public final String TAG = this.getClass().getSimpleName(); String currentFileUrl = ""; private FaceAdapter faceAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); faceAdapter = new FaceAdapter(this); //android版本在6.0以上 if (Build.VERSION.SDK_INT >= 23) { System.out.println("版本正确"); checkPermission(); } else { System.out.println("版本过低"); } binding.btnChoosePicture.setOnClickListener(view -> getPhoto()); binding.btnIdentifyPicture.setOnClickListener(view -> identifyFacePhoto()); binding.btnFaceLogout.setOnClickListener(view -> LogoutUser()); binding.ivFacepicture.setOnClickListener(view -> getPhoto()); } private void LogoutUser() { Hawk.delete("token"); Intent intent = new Intent(FaceDetectionActivity.this, LoginActivity.class); startActivity(intent); } //获取人脸照片 private void getPhoto() { CharSequence[] items = { "拍照", "图库" };// 裁剪items选项 // 弹出对话框提示用户拍照或者是通过本地图库选择图片 new AlertDialog.Builder(this) .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { // 选择了拍照 case 0: Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, TAKE_PHOTO); break; // 调用系统图库 case 1: // 创建Intent,用于打开手机本地图库选择图片 Intent intent1 = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // 启动intent打开本地图库 startActivityForResult(intent1, LOCAL_CROP); break; } } }).show(); } /** * 调用startActivityForResult方法启动一个intent后, * 可以在该方法中拿到返回的数据 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case TAKE_PHOTO:// 拍照 if (resultCode == RESULT_OK) { final Bitmap photo = data.getParcelableExtra("data"); //将bitmap照片放入系统相册,并将照片给url currentFileUrl = AppContext.saveImageToGallery(this, photo); binding.ivFacepicture.setImageBitmap(photo); Log.d(TAG, "onActivityResult: " + currentFileUrl); } break; case LOCAL_CROP:// 系统图库 if (resultCode == RESULT_OK) { Uri uri = data.getData(); binding.ivFacepicture.setImageURI(uri); currentFileUrl = AppContext.getRealPathFromURI(this, uri); Log.d(TAG, "onActivityResult: " + currentFileUrl); } break; } } private void identifyFacePhoto() { if (TextUtils.isEmpty(currentFileUrl)) { AppContext.showToast("请先选择人脸照片"); return; } else { binding.progressBar.setVisibility(View.VISIBLE); File file = new File(currentFileUrl); MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), RequestBody.create(MediaType.parse("image/*"), file)); RequestBody body = RequestBody.create(MediaType.parse("text/plain"), "" + Hawk.get("token")); NetworkApi.createService(ApiService.class) .uploadFacePhoto2(part, body) .compose(NetworkApi.applySchedulers(new BaseObserver<ResponseBody>() { @Override public void onSuccess(ResponseBody responseBody) { String result = AppContext.doJson(responseBody); String face_list = null; FaceBean.ResultBean faceListBean = null; try { JSONObject jsonObject = new JSONObject(result); face_list = jsonObject.getString("result"); KLog.d(TAG, face_list); Gson gson = new Gson(); faceListBean = gson.fromJson(String.valueOf(new JSONObject(face_list)), FaceBean.ResultBean.class); } catch (JSONException e) { e.printStackTrace(); } if (faceListBean != null) { showListFace(faceListBean); // binding.tvIdentifyFaceRusult.setText(AppContext.doJson(responseBody)); } else { AppContext.showToast("识别返回接口数据为空"); KLog.d(TAG, "识别返回接口数据为空"); binding.progressBar.setVisibility(View.GONE); } } @Override public void onFailure(Throwable e) { binding.progressBar.setVisibility(View.GONE); KLog.d(TAG, e.toString()); AppContext.showToast("访问失败"); } })); } } //测试了一下 //展示泪飙 private void showListFace(FaceBean.ResultBean faceListBean) { LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); binding.ryFacePeople.setLayoutManager(layoutManager); binding.ryFacePeople.setAdapter(faceAdapter); binding.progressBar.setVisibility(View.GONE); faceAdapter.updateFaceList(faceListBean.getFace_list()); } private void checkPermission() { ActivityCompat.requestPermissions(FaceDetectionActivity.this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, REQUEST_CODE); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { //权限的申请结果返回 case REQUEST_CODE: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //已授权 AppContext.showToast("授权成功"); } else { //未授权 AppContext.showToast("授权被拒绝"); } } } } @Override public void onBackPressed() { super.onBackPressed(); finish(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。