记阿里云人脸识别集成
一、到阿里云生成Access Key和Access Key Secret。
二、添加.jar包
三、编辑页面,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginLeft="20dp"android:orientation="vertical"tools:context="com.xdj.anew.MainActivity"><ImageViewandroid:id="@+id/image"android:layout_width="80dp"android:layout_height="80dp"android:src="@mipmap/ic_launcher" /><TextViewandroid:id="@+id/txt1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="上传身份证" /><ImageViewandroid:id="@+id/image2"android:layout_width="80dp"android:layout_height="80dp"android:layout_marginTop="10dp"android:src="@mipmap/ic_launcher" /><TextViewandroid:id="@+id/txt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="人脸验证" /><TextViewandroid:id="@+id/verify"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="开始验证"/></LinearLayout>
四、选择图片(分别选择相册)
@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.txt://相机
// startCamera();openCamera(this);break;case R.id.txt1://相册gallery();break;case R.id.verify:getVerify();break;}}
/*** 从相册获取*/public void gallery() {// 激活系统图库,选择一张图片Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/*");// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_GALLERYstartActivityForResult(intent, RESULT_CAMERA_IMAGE);}
写一个相机类进行调用
public class CameraUtil {public static File tempFile;public static final int PHOTO_REQUEST_CAREMA = 3;// 拍照 public static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 2;// 拍摄视频 public static Uri uri_;/*** 打开相机拍照 ** @param activity*/public static void openCamera(Activity activity) {//獲取系統版本 int currentapiVersion = android.os.Build.VERSION.SDK_INT;// 激活相机 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 判断存储卡是否可以用,可用进行存储 if (hasSdcard()) {SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");String filename = timeStampFormat.format(new Date());tempFile = new File(Environment.getExternalStorageDirectory(),filename + ".jpg");if (currentapiVersion < 24) {// 从文件中创建uri uri_ = Uri.fromFile(tempFile);intent.putExtra(MediaStore.EXTRA_OUTPUT, uri_);} else {//兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(1);contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());uri_ = activity.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);intent.putExtra(MediaStore.EXTRA_OUTPUT, uri_);Log.d("sjc", "uriuri>>>"+ uri_);}}// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA activity.startActivityForResult(intent, PHOTO_REQUEST_CAREMA);}/*** 打开相机录像 */public static void startToVideo(Activity activity) {//獲取系統版本 int currentapiVersion = android.os.Build.VERSION.SDK_INT;Uri fileUri = null;File file = null;Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);try {file = createMediaFile();if (file.exists()) {fileUri = Uri.fromFile(file); // create a file to save the video }} catch (IOException e) {e.printStackTrace();}if (currentapiVersion < 24) {intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high } else {//兼容android7.0 ContentValues contentValues = new ContentValues(1);contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());Uri uri = activity.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);}// start the Video Capture Intent activity.startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);}/* * 判断sdcard是否被挂载 */public static boolean hasSdcard() {return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);}/*** 创建保存录制得到的视频文件 ** @return* @throws IOException*/public static File createMediaFile() throws IOException {if (hasSdcard()) {File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "CameraVideos");if (!mediaStorageDir.exists()) {if (!mediaStorageDir.mkdirs()) {return null;}}// Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "VID_" + timeStamp;String suffix = ".mp4";File mediaFile = new File(mediaStorageDir + File.separator + imageFileName + suffix);return mediaFile;}return null;}
}
五、在activity进行图片回调接收,并显示
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode != RESULT_OK) {return;}if (requestCode == RESULT_CAMERA_IMAGE) {// 从相册返回的数据if (data != null) {// 得到图片的全路径uri = data.getData();image.setImageURI(uri);}}if (requestCode == PHOTO_REQUEST_CAREMA) {//照的相片try {//图片解析成Bitmap对象mBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri_));image2.setImageBitmap(mBitmap);} catch (FileNotFoundException e) {e.printStackTrace();}}}
六、抄下官方写好的请求头:
public class AESDecode {
/*
* 计算MD5+BASE64
*/
public static String MD5Base64(String s) {
if (s == null)
return null;
String encodeStr = "";
byte[] utfBytes = s.getBytes();
MessageDigest mdTemp;
try {
mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(utfBytes);
byte[] md5Bytes = mdTemp.digest();
BASE64Encoder b64Encoder = new BASE64Encoder();
encodeStr = b64Encoder.encode(md5Bytes);
} catch (Exception e) {
throw new Error("Failed to generate MD5 : " + e.getMessage());
}
return encodeStr;
}
/*
* 计算 HMAC-SHA1
*/
public static String HMACSha1(String data, String key) {
String result;
try {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes());
result = (new BASE64Encoder()).encode(rawHmac);
} catch (Exception e) {
throw new Error("Failed to generate HMAC : " + e.getMessage());
}
return result;
}
/*
* 等同于javaScript中的 new Date().toUTCString();
*/
public static String toGMTString(Date date) {
SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
return df.format(date);
}
/*
* 发送POST请求
*/
public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
int statusCode = 200;
try {
URL realUrl = new URL(url);
/*
* http header 参数
*/
String method = "POST";
String accept = "application/json";
String content_type = "application/json";
String path = realUrl.getFile();
String date = toGMTString(new Date());
// 1.对body做MD5+BASE64加密
String bodyMd5 = MD5Base64(body);
String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date + "\n"
+ path;
// 2.计算 HMAC-SHA1
String signature = HMACSha1(stringToSign, ak_secret);
// 3.得到 authorization header
String authHeader = "Dataplus " + ak_id + ":" + signature;
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", accept);
conn.setRequestProperty("content-type", content_type);
conn.setRequestProperty("date", date);
conn.setRequestProperty("Authorization", authHeader);
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(body);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
statusCode = ((HttpURLConnection)conn).getResponseCode();
if(statusCode != 200) {
in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream()));
} else {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
if (statusCode != 200) {
throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
}
return result;
}
/*
* GET请求
*/
public static String sendGet(String url, String ak_id, String ak_secret) throws Exception {
String result = "";
BufferedReader in = null;
int statusCode = 200;
try {
URL realUrl = new URL(url);
/*
* http header 参数
*/
String method = "GET";
String accept = "application/json";
String content_type = "application/json";
String path = realUrl.getFile();
String date = toGMTString(new Date());
// 1.对body做MD5+BASE64加密
// String bodyMd5 = MD5Base64(body);
String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date + "\n" + path;
// 2.计算 HMAC-SHA1
String signature = HMACSha1(stringToSign, ak_secret);
// 3.得到 authorization header
String authHeader = "Dataplus " + ak_id + ":" + signature;
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", accept);
connection.setRequestProperty("content-type", content_type);
connection.setRequestProperty("date", date);
connection.setRequestProperty("Authorization", authHeader);
connection.setRequestProperty("Connection", "keep-alive");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
statusCode = ((HttpURLConnection)connection).getResponseCode();
if(statusCode != 200) {
in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream()));
} else {
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
}
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (statusCode != 200) {
throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
}
return result;
}
public static void main(String[] args) throws Exception {
// 发送POST请求示例
String ak_id1 = "NMV.............5jv"; //用户ak
String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
//根据需求修改为https://dtplus-cn-shanghai.data.aliyuncs.com/face/verify(人脸对比)
String url = "https://shujuapi.aliyun.com/org_code/service_code/api_name";
// String body = "{\"type\":1,\"content_1\": \"" + photo1 + "\", \"content_2\":\"" + photo2 + "\"}";//photo1 为图片base64格式
String body = "{\"param1\": \"xxx\", \"param2\":\"xxx\"}";
System.out.println("response body:" + sendPost(url, body, ak_id, ak_secret));
// 发送GET请求
String ak_id1 = "NMV.............5jv"; //用户ak
String ak_secret1 = "Fgs...............3zu"; // 用户ak_secret
String url1 = "https://shujuapi.aliyun.com/org_code/service_code/api_name?param1=xxx¶m2=xxx";
System.out.println("response body:" + sendGet(url1, ak_id1, ak_secret1));
}
}
七、请求网络对面相似度
ps:图片uri转base64:
photo1 = ImageUtils.bitmapToString(getPath(uri));
photo2 = ImageUtils.bitmapToString(getPath(uri_));
public class ImageUtils {// 根据路径获得图片并压缩,返回bitmap用于显示public static Bitmap getSmallBitmap(String filePath) {final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filePath, options);// Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, 480, 800);// Decode bitmap with inSampleSize setoptions.inJustDecodeBounds = false;return BitmapFactory.decodeFile(filePath, options);}//计算图片的缩放值public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {final int heightRatio = Math.round((float) height/ (float) reqHeight);final int widthRatio = Math.round((float) width / (float) reqWidth);inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;}return inSampleSize;}//把bitmap转换成Stringpublic static String bitmapToString(String filePath) {Bitmap bm = getSmallBitmap(filePath);ByteArrayOutputStream baos = new ByteArrayOutputStream();//1.5M的压缩后在100Kb以内,测试得值,压缩后的大小=94486字节,压缩后的大小=74473字节//这里的JPEG 如果换成PNG,那么压缩的就有600kB这样bm.compress(Bitmap.CompressFormat.JPEG, 40, baos);byte[] b = baos.toByteArray();Log.d("d", "压缩后的大小=" + b.length);return Base64.encodeToString(b, Base64.DEFAULT);}}
private String getPath(Uri uri) {String[] projection = {MediaStore.Video.Media.DATA};Cursor cursor = managedQuery(uri, projection, null, null, null);int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);cursor.moveToFirst();return cursor.getString(column_index);
}
请求网络进行图片对比
private boolean getVerify() {new Thread(new Runnable() {@Overridepublic void run() {try {photo1 = ImageUtils.bitmapToString(getPath(uri));photo2 = ImageUtils.bitmapToString(getPath(uri_));String body = "{\"type\":1,\"content_1\": \"" + photo1 + "\", \"content_2\":\"" + photo2 + "\"}";final String s = sendPost(url, body, ak_id, ak_secret);//解析resultfinal Bean jsonObject = JSON.parseObject(s, Bean.class);runOnUiThread(new Runnable() {@Overridepublic void run() {if (jsonObject.getConfidence() > 80){Toast.makeText(MainActivity.this,"验证成功",Toast.LENGTH_SHORT).show();}else {Toast.makeText(MainActivity.this,"验证失败",Toast.LENGTH_SHORT).show();}}});} catch (final Exception e) {e.printStackTrace();runOnUiThread(new Runnable() {@Overridepublic void run() {Log.v("sjc——", e.toString());Toast.makeText(MainActivity.this, "对比失败>"+e, Toast.LENGTH_SHORT).show();}});}}}).start();return true;}
解析返回数据,判断相似度,根据个人需求判断相似度达到多少为验证通过
八、 注意 相机的请求权限,直接使用uri是不行的,经网上各种查阅,可以使用provider,在manifest 中注册provider
<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="包名.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"/></provider>
res目录下新建xml文件夹,并新建文件file_paths(文件名可以随便取),主要是里边的配置
file_paths文件内容如下
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path path="pasth" name="camera_photos" /><external-path name="my_images" path="Android/data/com.example.wmz.network/files/Pictures/" /><external-path name="images" path="Pictures/" /><external-path name="dcim" path="DCIM/" />
</paths>
没什么写博客的经验,写的不好望理解。
本次项目用jar包:
记阿里云人脸识别集成相关推荐
- 阿里云人脸识别公测使用说明
概述 之前阿里云人脸识别只提供人脸检测,人脸属性及人脸对比三个API接口,关于这方面的介绍及使用细节,可以参考阿里云人脸识别使用流程简介,之前使用的服务地址为:dtplus-cn-shanghai.d ...
- 阿里云人脸识别C#调用示例参考
概述 前面介绍了关于阿里云人脸识别Java调用示例参考,本文主要介绍C#调用阿里云人脸识别服务,参数等的获取参考阿里云人脸识别使用流程简介. Code Sample 1.使用网络图片 using Sy ...
- 阿里云人脸识别C#调用示例参考 1
概述 前面介绍了关于阿里云人脸识别Java调用示例参考,本文主要介绍C#调用阿里云人脸识别服务,参数等的获取参考阿里云人脸识别使用流程简介. Code Sample 1.使用网络图片 using Sy ...
- 阿里云人脸识别使用流程简介
概述 之前写过一篇关于Java 使用阿里云人脸识别的博客,介绍了如何使用网络及本地图片基于Rest API调用人脸识别服务.实际的使用中发现很多用户因为之前没有使用过人脸识别,对前期的一些参数配置还是 ...
- 阿里云人脸识别PHP调用示例参考
概述 前面分别给出了关于阿里云人脸识别Java调用示例参考.阿里云人脸识别C#调用示例参考.阿里云人脸识别Python3调用示例参考 .本文主要介绍PHP调用阿里云人脸识别服务,参数等的获取参考阿里云 ...
- 调用阿里云人脸识别接口示例
下面我为大家展示一下我调用阿里云人脸识别接口的示例 首先说下开发环境,springboot 开发的 org.apache.commons.codec.binary.Base64; 这个主要是用来进行b ...
- 阿里云人脸识别接口--心得分享
一:对接阿里云人脸识别接口的工具类 注意:如果你的图片已经转换为base64的编码以后参数是content_1,后面要加type请求参数,我这里是通过图片的url对比的 public class Fa ...
- 阿里云人脸识别接口调用卡顿,超时
阿里云人脸识别接口调用卡顿 在服务端通过pom引入阿里云人脸识别sdk的时候,如果生产环境在内网开通了网络策略连接了 cloudauth.aliyuncs.com 这个地址. 但是sdk调用人脸识别服 ...
- 阿里云人脸识别新版SDK对接(java)
我自认为不想做curd程序员,但是免不了的会对数据基本原子操作进行处理,项目开发过程中的增删改查少不了的,但是又不甘心于curd下去,所以想要在掌握现有知识的基础上,甚至逼迫自己去学习一些东西,去接触 ...
最新文章
- 转换前台javascript传递过来的时间字符串到.net的DateTime
- 自考第一章计算机基础知识,2018年自考计算机网络技术基础复习资料:第一章...
- 第二天 PYTHON 基本数据类型 - 数字 - 字符串
- .NET Core开发实战(第22课:异常处理中间件:区分真异常与逻辑异常)--学习笔记(上)...
- 现代软件工程 结对编程 (II) 电梯调度
- bzoj 2555: SubString
- python粘贴代码到word_python怎么粘贴代码
- 数据分析之学术前沿分析- 任务2
- 人工智能基础——知识的表示方法,产生式表示法
- Origin | 数据处理 | 公式编辑栏 | F(x)栏的使用 | 数据提取 | 数据筛选及删减
- 不仅仅生成图片,用GAN做无监督的异常检测
- Windows cmd常用命令行命令
- mo汇编指令_moshell常用指令描述
- python语言读后感_《利用Python进行数据分析》读书笔记
- 《狂飙》壁纸大嫂如此惊艳,做成日历壁纸天天看
- python逐行读取excel_用python读取excel需要哪些技能
- IOS 文本操作笔记——CHARACTERSET
- Android Gson 操作
- Blazor University (21)使用 RenderFragments 模板化组件 —— 传递占位符
- 51单片机学习笔记-2数码管显示
热门文章
- 多维数组(2019.10.25)
- 机房计算机课提交作业,信息技术课机房上课规则
- 使用GitHub Pages+Hexo 搭建个人网站详细教程
- Oracle Database 12c Security - 13. An Applied Approach to Multitenancy and Cloud Security
- cobaltstrike权限维持
- 大屏LCD12864_stc8a8k使用说明
- Spring Cloud Stream核心原理介绍
- Spring Boot | 第零章:开启新纪元
- ISO9001质量管理体系认证详细介绍
- [魔兽]Grubby兽族的操作编队详解