import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import sun.misc.BASE64Encoder;
/**
* @Copyright: (C),2018,. Co., Ltd.
* @ClassName: AliyunFaceVerify 阿里云人脸识别API
* @Author: XXXXXX
* @Date: 2019年8月5日 下午3:01:23
*/
public class AliyunFaceVerify {
private final static Logger logger = LoggerFactory.getLogger(AliyunFaceVerify.class.getName());
// 产品域名,开发者无需替换
private static final String url = "https://dtplus-cn-shanghai.data.aliyuncs.com/face/verify";
// 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
private static final String accessKeyId = "XXXXXXXXXXXX";
private static final String accessKeySecret = "XXXXXXXX";
// 比较相似比
private static final Double confidence = 75.00;
private Boolean flag; // 比对结果 true : false
private Double result; // 比对后相似比
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
public Double getResult() {
return result;
}
public void setResult(Double result) {
this.result = result;
}
/*
* 计算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 content_type = "application/octet-stream";
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 content_type = "application/octet-stream";
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;
}
/**
* 将本地图片编码为base64
*
* @param file
* @return
* @throws Exception
*/
public static String encodeImageToBase64(File file) throws Exception {
// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
// loggerger.info("图片的路径为:" + file.getAbsolutePath());
InputStream in = null;
byte[] data = null;
// 读取图片字节数组
try {
in = new FileInputStream(file);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
throw new Exception("图片上传失败,请联系客服!");
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
String base64 = encoder.encode(data);
return base64;// 返回Base64编码过的字节数组字符串
}
/**
* 将网络图片编码为base64
*
* @param url
* @return
* @throws BusinessException
*/
public static String encodeImageToBase64(URL url) throws Exception {
// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
logger.info("图片的路径为:" + url.toString());
// 打开链接
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
// 设置请求方式为"GET"
conn.setRequestMethod("GET");
// 超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
// 通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
// 得到图片的二进制数据,以二进制封装得到数据,具有通用性
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 创建一个Buffer字符串
byte[] buffer = new byte[1024];
// 每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
// 使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
// 关闭输入流
inStream.close();
byte[] data = outStream.toByteArray();
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
String base64 = encoder.encode(data);
// logger.info("网络文件[{}]编码成base64字符串:[{}]", url.toString(), base64);
return base64;// 返回Base64编码过的字节数组字符串
} catch (IOException e) {
e.printStackTrace();
throw new Exception("图片上传失败,请联系客服!");
}
}
/**
* @Title: CompareImageResult
* @Description: 比较数据库存储的图片地址 和 手机端 传上来 的 file 文件 比对
* @param pic1 为上传图片 pic2 为用户图片
* @param pic2
* @return String返回类型
* @throws Exception
* @throws:
* @Author: XXXXXX
* @Date: 2019年8月5日 下午3:17:00
*/
public AliyunFaceVerify CompareImageResult(String pic1, String pic2) throws Exception {
String ImageA = "'" + pic1 + "'";
String ImageB = "'" + pic2 + "'";
String body = "{\"type\":0,\n" + "\"image_url_1\":" + ImageA + ",\n" + "\"image_url_2\":" + ImageB + "\n" + "}";
String resutl = sendPost(url, body, accessKeyId, accessKeySecret);
JSONObject jsonObj = JSON.parseObject(resutl);
// 大于预设定的相似度返回true否则
System.out.println("返回confidence:" + jsonObj.getString("confidence") + "----" + "预设confidence:" + confidence);
AliyunFaceVerify AFV = new AliyunFaceVerify();
AFV.setFlag(Double.valueOf(jsonObj.getString("confidence")) >= confidence ? true : false);
AFV.setResult(Double.valueOf(jsonObj.getString("confidence")));
return AFV;
}
public static void main(String[] args) throws Exception {
AliyunFaceVerify AA = new AliyunFaceVerify();
AA = AA.CompareImageResult(
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542203663452&di=12633ef717e4ee26b3a3da711baa348d&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F14ce36d3d539b60083e4ad8be250352ac65cb7e0.jpg",
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542203663452&di=12633ef717e4ee26b3a3da711baa348d&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F14ce36d3d539b60083e4ad8be250352ac65cb7e0.jpg");
System.out.println(JSON.toJSON(AA));
// 上传本地图片
// Request body
// String pic_path = "C:\\Users\\NuoleAQ\\Desktop\\11.jpg";// 本地图片的路径
// String pic_path2 = "C:\\Users\\NuoleAQ\\Desktop\\22.jpg";// 本地图片的路径
// File picBase64 = new File(pic_path);
// File picBase642 = new File(pic_path2);
// String pic = encodeImageToBase64(picBase64);
// String pic2 = encodeImageToBase64(picBase642);
// String pic = encodeImageToBase64(pic_path);
// String pic2 = encodeImageToBase64(pic_path2);
// 提出base64编码的换行符问题
// String data = pic.replaceAll("[\\s*\t\n\r]", "");
// String data2 = pic2.replaceAll("[\\s*\t\n\r]", "");
// data = "'" + data + "'";
// data2 = "'" + data2 + "'";
// String body = "{\"type\":1,\n" + "\"content_1\":" + data + ",\n" +
// "\"content_2\":" + data2 + "\n" + "}";
// String re = sendPost(url, body, accessKeyId, accessKeySecret);
// getJsonData(re);
}
public static void getJsonData(String re) {
// String s = "{\"confidence\":80.6434326171875,\"thresholds\":[61.0,69.0,75.0],\"rectA\":[92,50,74,87],\"rectB\":[171,101,118,137],\"errno\":0,\"request_id\":\"754af075-1d6b-4cb0-a709-7015eac53a7c\"}";
JSONObject jsonObj = JSON.parseObject(re);
String confidence = jsonObj.getString("confidence");
System.out.println(confidence);
}
}