赞
踩
今天做了一套二级Java题,直接就绝望了。选择题就得了25分,错了将近一半,大后天就考了,忐忑。。
前天晚上和大前天晚上加班写了一个讯飞的一个人脸识别,结果昨天电脑系统让我安装Linux按的系统炸了。去他的,按了一下午系统昨天晚上干到十二点又写了一遍,不仅写的时间缩短了,而且更加清楚套路了。
1.从官网上申请服务,会给你个id也就是访问的key。吧这个记下来,下载人脸识别的SDK包括两个jar,和几个二进制文件。SDk里面有例程,导入Eclipce中运行无误后就可以看结构仿写了。
2.因为是用Android Studio写的所以较麻烦,需要将jar文件和so文件放入正确的位置。
3.主要分为两个类写的,第一个类就是进行照完的人脸进行裁剪类,这个是使用android自带的裁剪器,进行相应的配置,这个类里面主要是裁剪,对摄影的角度的判断,旋转图片,保存图片这几个方法。
4.第二个类就是通过SDK类进行识别了,首先需要将自己的申请的key在初始化SDK的时候添加进去,作为App唯一的标志允许访问服务,这个类主要是分三大块:Button的监听、对返回的数据进行Json解析判断、对Intent的监听(主要是照完相后对图片进行裁剪)。
新建jniLibs文件夹放入so文件 将Msc.jar Sunflower.jar文件放入libs文件夹中并添加进编译路径。
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.CAMERA" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
- <uses-feature android:name="android.hardware.camera" />
- <uses-feature android:name="android.hardware.camera.autofocus" />
- package com.example.hejingzhou.facerecognition;
-
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.graphics.Bitmap;
- import android.graphics.Matrix;
- import android.media.ExifInterface;
- import android.net.Uri;
- import android.os.Environment;
- import android.provider.MediaStore;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
-
- /**
- * Created by Hejingzhou on 2016/3/22.
- */
- public class HeadTrim {
- public final static int REQUEST_PICTURE_CHOOSE = 1;
- public final static int REQUEST_CAMERA_IMAGE = 2;
- public final static int REQUEST_CROP_IMAGE = 3;
-
- /**
- * 裁剪图片 android自带的裁剪
- * @param activity
- * @param uri
- */
- public static void corpPicture(Activity activity,Uri uri){
- Intent innerIntent = new Intent("com.android.camera.action.CROP");//启用自带裁剪
- innerIntent.setDataAndType(uri, "image/*");
- innerIntent.putExtra("crop", "ture");//裁剪小正方形,不然没有裁剪功能,只能选取
- innerIntent.putExtra("aspectX", 1);//放大缩小缩放比例
- innerIntent.putExtra("aspectY", 1);//缩放比例 1 :1
- innerIntent.putExtra("outputX", 320);
- innerIntent.putExtra("outputY", 320);//限制图片大小
- innerIntent.putExtra("return-data",true);
-
- //切图大小不足 320 会出现黑框,防止出现黑框并输出
- innerIntent.putExtra("scale",true);
- innerIntent.putExtra("scaleUpIfNeeded",true);
- File imageFile = new File(getImagePath(activity.getApplicationContext()));//从这个文件路径创建文件
- innerIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(imageFile));
- //MediaStore.EXTRA_OUTPUT 表示内容解析器被用来存储请求的Uri的图像或视频
- innerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//带上裁剪好的图片传递出去
- activity.startActivityForResult(innerIntent,REQUEST_CROP_IMAGE);
- }
-
- /**
- * 获取裁剪的图片路径
- * @param context
- * @return
- */
- public static String getImagePath(Context context){
- String path;
- if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
- //如果当前存储的状态 是 不能挂载和读写的
- path = context.getFilesDir().getAbsolutePath();//路径就等于这个文件的绝对路径(从根开始)
- }else {
- path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/msc/";
- }
- if(!path.endsWith("/")){ //与路径的最后一个字符进行比较如果不是“/”那么就添加“/”
- path += "/";
- }
- File folder = new File(path);
- if(folder != null && !folder.exists()){//如果文件不为空 或者不存在,创建这个文件的文件夹
- folder.mkdirs();
- }
- path += "ifd.jpg";
- return path;
- }
-
- /**
- * 读取图片的属性 :的角度
- * @param path
- * @return
- */
- public static int readPictureDegree(String path){
- int degree = 0;//度
- try {
- ExifInterface exifInterface = new ExifInterface(path);//阅读和写作在JPEG文件的Exif标记类
- int orientation = exifInterface.getAttributeInt(
- //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;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return degree;
- }
-
- /**
- * 旋转图片
- * @param angle 旋转角度
- * @param bitmap 原图
- * @return 旋转后的 bitmap
- */
- public static Bitmap rotateImage(int angle,Bitmap bitmap){
- Matrix matrix = new Matrix();
- matrix.postRotate(angle); //postconcats与指定的旋转矩阵
- Bitmap resizedBitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
- /**
- * createBitmap 返回一个不可变的位图从源位图的子集
- * @param source The bitmap we are subsetting
- * @param x The x coordinate of the first pixel in source
- * @param y The y coordinate of the first pixel in source
- * @param width The number of pixels in each row
- * @param height The number of rows
- * @param m Optional matrix to be applied to the pixels 可选的矩阵应用到像素
- * @param filter true if the source should be filtered. 如果源应筛选,true
- * Only applies if the matrix contains more than just
- * translation.
- */
- return resizedBitmap;
- }
-
- /**
- * 保存图片
- * @param context
- * @param bitmap
- */
- public static void saveBitmapToFile(Context context, Bitmap bitmap) {
- String file_path = getImagePath(context);
- File file = new File(file_path);
- FileOutputStream fileOutputStream;
- try {
- fileOutputStream = new FileOutputStream(file);
- bitmap.compress(Bitmap.CompressFormat.JPEG,85,fileOutputStream);
- fileOutputStream.flush();
- fileOutputStream.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- }
这个类中的裁剪方法挺好的,记住在别处也会用的着。
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">package com.example.hejingzhou.facerecognition;</span>
<span style="font-family: Arial, Helvetica, sans-serif;">import android.app.ProgressDialog;</span>
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.database.Cursor;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.media.MediaScannerConnection;
- import android.net.Uri;
- import android.os.Environment;
- import android.provider.MediaStore;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.text.TextUtils;
- import android.util.Log;
- import android.view.View;
- import android.view.WindowManager;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.Toast;
-
- import com.iflytek.cloud.ErrorCode;
- import com.iflytek.cloud.FaceRequest;
- import com.iflytek.cloud.RequestListener;
- import com.iflytek.cloud.SpeechConstant;
- import com.iflytek.cloud.SpeechError;
- import com.iflytek.cloud.SpeechUtility;
-
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
-
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.UnsupportedEncodingException;
- import java.util.Currency;
-
- public class MainActivity extends AppCompatActivity implements View.OnClickListener{
- private String TAG = getClass().getCanonicalName();
- private final int REQUEST_PICTURE_CHOOSE = 1;
- private final int REQUEST_CAMERA_IMAGES = 2;
- private FaceRequest faceRequest;
- private Toast toast;
- private byte[] imageData = null;
- private Bitmap image = null;
- private EditText editTextUserPassword;
- private String UserPassword;
- private ProgressDialog progressDialog;
- private File pictureFile;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- }
-
- private void init() {
- this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
- SpeechUtility.createUtility(this, "appid=" + getString(R.string.app_key));//初始化SDK 千万不能忘记写appid后边的等号 id是自己其官网上申请的
- //忘记会报 10274无效 key
- faceRequest = new FaceRequest(this);
- findViewById();
- toast = Toast.makeText(this,"",Toast.LENGTH_SHORT);
- progressDialog = new ProgressDialog(this);
- progressDialog.setCancelable(true);//设置是否可取消
- progressDialog.setTitle("请稍等...");
- progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- if (null != faceRequest) {
- faceRequest.cancel();
- }
- }
- });
- }
-
- private void findViewById() {
- editTextUserPassword = (EditText)findViewById(R.id.editTextUserPassword);
- findViewById(R.id.buttonRegister).setOnClickListener(MainActivity.this);
- findViewById(R.id.buttonPicture).setOnClickListener(MainActivity.this);
- findViewById(R.id.buttonVerification).setOnClickListener(MainActivity.this);
- findViewById(R.id.imageViewHead).setOnClickListener(MainActivity.this);
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()){
- case R.id.buttonPicture:
- pictureFile = new File(Environment.getExternalStorageDirectory(),
- "picture"+System.currentTimeMillis()/1000+".jpg");
- Intent picIntent = new Intent();
- picIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
- picIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(pictureFile));
- picIntent.putExtra(MediaStore.Images.Media.ORIENTATION,0);
- startActivityForResult(picIntent,REQUEST_CAMERA_IMAGES);
- break;
- case R.id.buttonRegister:
- UserPassword = ((EditText)findViewById(R.id.editTextUserPassword)).getText().toString();
- if(TextUtils.isEmpty(UserPassword)){
- showToast("请输入您的密钥");
- return;
- }else if(null != imageData){
- progressDialog.setMessage("注册中...");
- progressDialog.show();
- faceRequest.setParameter(SpeechConstant.AUTH_ID, UserPassword);//将授权标识和密码上传服务器记录
- faceRequest.setParameter(SpeechConstant.WFR_SST,"reg");//业务类型train Or verify
- faceRequest.sendRequest(imageData,requestListener);
- }else showToast("请先进行图像拍摄...");
- break;
- case R.id.buttonVerification:
- UserPassword = ((EditText)findViewById(R.id.editTextUserPassword)).getText().toString();
- if(TextUtils.isEmpty(UserPassword)){
- showToast("密钥不能为空哦...");
- }else if(imageData != null){
- progressDialog.setMessage("验证中,请稍等...");
- progressDialog.show();//6--12字符 不能以数字开头
- faceRequest.setParameter(SpeechConstant.AUTH_ID, UserPassword);
- faceRequest.setParameter(SpeechConstant.WFR_SST,"verify");
- faceRequest.sendRequest(imageData,requestListener);
- }else showToast("请先捕捉头像...");
- break;
- }
- }
-
- /**
- * 处理拍完照后,跳转到裁剪界面
- * @param requestCode
- * @param resultCode
- * @param data
- */
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- Log.i(TAG, "运行到了onActivityResult");
- if(resultCode != RESULT_OK){
- Log.i(TAG,"requestCode未成功");
- return;
- }
- String fileSrc = null;
- if(requestCode == REQUEST_PICTURE_CHOOSE){
- if("file".equals(data.getData().getScheme())){
- fileSrc = data.getData().getPath();
- Log.i(TAG,"file "+fileSrc);
- }else {
- String[] proj = {MediaStore.Images.Media.DATA};
- Cursor cursor = getContentResolver().query(data.getData(), proj, null, null, null);
- cursor.moveToFirst();
- int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- fileSrc = cursor.getString(idx);
- cursor.close();
- }
- HeadTrim.corpPicture(this, Uri.fromFile(new File(fileSrc)));
- }else if(requestCode == REQUEST_CAMERA_IMAGES){
- if(null == pictureFile){
- showToast("拍照失败,请重试...");
- return;
- }
- fileSrc = pictureFile.getAbsolutePath();
- updataGallery(fileSrc);
- HeadTrim.corpPicture(this,Uri.fromFile(new File(fileSrc)));
- }else if(requestCode == HeadTrim.REQUEST_CROP_IMAGE){
- Bitmap bitmap = data.getParcelableExtra("data");
- Log.i(TAG,"bitmp是否为空");
- if(null != bitmap){
- HeadTrim.saveBitmapToFile(MainActivity.this,bitmap);
- }
- fileSrc = HeadTrim.getImagePath(MainActivity.this);//获取图片保存路径
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- image = BitmapFactory.decodeFile(fileSrc,options);
- options.inSampleSize = Math.max(1, (int) Math.ceil(Math.max(
- (double) options.outWidth / 1024f,
- (double) options.outHeight / 1024f
- )));
- options.inJustDecodeBounds = false;
- image = BitmapFactory.decodeFile(fileSrc,options);
- //如果imageBitmap 为空图片不能正常获取
- if(null == image){
- showToast("图片信息无法正常获取");
- return;
- }
- int degree = HeadTrim.readPictureDegree(fileSrc);
- if(degree != 0){
- image = HeadTrim.rotateImage(degree,image);
- }
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- image.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream);
- imageData = byteArrayOutputStream.toByteArray();
- ((ImageView)findViewById(R.id.imageViewHead)).setImageBitmap(image);
- }
- }
-
- @Override
- public void finish() {
- if(null != progressDialog){
- progressDialog.dismiss();
- }
- super.finish();
- }
-
- private void updataGallery(String fileName) {
- MediaScannerConnection.scanFile(this, new String[]{fileName}, null,
- new MediaScannerConnection.OnScanCompletedListener() {
-
- @Override
- public void onScanCompleted(String path, Uri uri) {
-
- }
- });
- }
-
- /**
- * 请求对象监听 , 对服务器返回来的数据进行解析 JSON格式
- */
- private RequestListener requestListener = new RequestListener() {
- @Override
- public void onEvent(int i, Bundle bundle) {
-
- }
-
- @Override
- public void onBufferReceived(byte[] bytes) {
- if(null != progressDialog){
- progressDialog.dismiss();
- }
- try {
- String result = new String(bytes,"utf-8");
- Log.i(TAG,result);
- JSONObject object = new JSONObject(result);
- String type = object.optString("sst");//获取业务类型
- if("reg".equals(type)){//注册
- register(object);
- }else if("verify".equals(type)){//校验
- verify(object);
- }else if("detect".equals(type)){
- detect(object);
- }else if("aligm".equals(type)){
- //align(object);
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void onCompleted(SpeechError speechError) {//完成后
- if(null != progressDialog){
- progressDialog.dismiss();
- }
- if(speechError != null ){
- switch (speechError.getErrorCode()){
- case ErrorCode.MSP_ERROR_ALREADY_EXIST:
- showToast("密钥已被注册,请更换后再试...");
- break;
- default:showToast(speechError.getPlainDescription(true));
- break;
- }
- }
- }
- };
- //检测
- private void detect(JSONObject object) throws JSONException{
- int ret = object.getInt("ret");
- if(ret != 0){
- showToast("检测失败");
- }else if("success".equals(object.get("rst"))){
- JSONArray jsonArray = object.getJSONArray("face");
- Paint paint = new Paint();
- paint.setColor(Color.RED);
- paint.setStrokeWidth(Math.max(image.getWidth(), image.getHeight()) / 100f);
-
- Bitmap bitmap = Bitmap.createBitmap(image.getWidth(),image.getHeight(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- canvas.drawBitmap(image,new Matrix(),null);
- for(int i = 0;i<jsonArray.length();i++){
- float x1 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("left");
- float y1 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("top");
- float x2 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("right");
- float y2 = (float) jsonArray.getJSONObject(i).getJSONObject("position").getDouble("bottom");
- paint.setStyle(Paint.Style.STROKE);
- canvas.drawRect(new Rect((int)x1,(int)x2,(int)x2,(int)y2),paint);
- }
- image = bitmap;
- ((ImageView)findViewById(R.id.imageViewHead)).setImageBitmap(image);
- }else {
- showToast("检测失败");
- }
- }
-
- /**
- * 校验
- * @param object
- */
- private void verify(JSONObject object) throws JSONException{
- int ret = object.getInt("ret");
- Log.i(TAG,"ret校验"+ret);
- if(ret != 0){
- showToast("校验失败..."+ret);
- }else if("success".equals(object.get("rst"))){
- if(object.getBoolean("verf")){
- showToast("验证通过");
- editTextUserPassword.setText(null);
- startActivity(new Intent(MainActivity.this,JumpActivity.class));
- }else if(!object.getBoolean("verg")){
- showToast("验证不通过");
- }else showToast("验证失败");
- }
- }
-
- /**
- * 如果收回的数据类型是注册 进行一下处理
- * @param object
- */
- private void register(JSONObject object) throws JSONException{
- int ret = object.getInt("ret");//解析ret返回值 0代表成功 -1失败 或者其他的错误异常代码
- if(ret != 0){
- showToast("注册失败");
- return;
- }else if("success".equals(object.get("rst"))){
- showToast("注册成功");
- editTextUserPassword.setText(null);
- }else showToast("注册失败,错误");
-
- }
-
- //土司对话框
- private void showToast(final String s){
- toast.setText(s);
- toast.show();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。