首先需要导入第三方包,在文末源码下载项目里面的libs文件夹下,或者到Face++官网下载(开发者工具与SDK中)
进入Face++注册账号
审核通过后,进入自己的应用,复制APIKEY 和API SECRET
Constant.java:
package com.example.howold;
public class Constant {
public static final String APP_KEY = "4f1b065b596540f5456805d4c2c2923a";
public static final String APP_SECRET = "Oge3CHP33ASirgJfrulMth-3gcLzD7Ts";
}
获取手机相册的图片显示到Imageview上:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, PICK_CODE);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == PICK_CODE) {
if (data != null) {
Uri uri = data.getData();
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
mCurrentPhotoStr = cursor.getString(index);
cursor.close();
resizePhoto();
mPhoto.setImageBitmap(mBitmapPhoto);
mTip.setText("Click Detect ==>");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void resizePhoto() {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>BitmapFactory.Options options = new BitmapFactory.Options();
<span style="white-space:pre"> </span>options.inJustDecodeBounds = true;
<span style="white-space:pre"> </span>BitmapFactory.decodeFile(mCurrentPhotoStr, options);
<span style="white-space:pre"> </span>double ratio = Math.max(options.outWidth * 1.0d / 1024f, options.outHeight * 1.0d / 1024f);
<span style="white-space:pre"> </span>options.inSampleSize = (int) Math.ceil(ratio);
<span style="white-space:pre"> </span>options.inJustDecodeBounds = false;
<span style="white-space:pre"> </span>mBitmapPhoto = BitmapFactory.decodeFile(mCurrentPhotoStr, options);
<span style="white-space:pre"> </span>}
mPhoto即自己的ImageView
建立一个工具类,实现Bitmap与Byte之间的转换
BitmapByteUtil.java:package Utils;
import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapByteUtil {
public Bitmap byteToBitmap(byte[] temp){
if(temp != null){
Bitmap bitmap = BitmapFactory.decodeByteArray(temp, 0, temp.length);
return bitmap;
}
return null;
}
public byte[] bitmapToByte(Bitmap photo){
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
if(photo != null){
photo.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
return null;
}
}
建立一个FaceppDetect类去获取JsonObject数据:
package Utils;
import org.apache.http.HttpRequest;
import org.json.JSONObject;
import com.example.howold.Constant;
import com.facepp.error.FaceppParseException;
import com.facepp.http.HttpRequests;
import com.facepp.http.PostParameters;
import android.graphics.Bitmap;
import android.util.Log;
public class FaceppDetect {
private BitmapByteUtil bitmapByteUtil = new BitmapByteUtil();
public interface CallBack{
void success(JSONObject result);
void error(FaceppParseException exception);
}
public static void detect(final Bitmap bitmap,final CallBack callBack){
new Thread(new Runnable() {
public void run() {
try {
BitmapByteUtil bitmapByteUtil = new BitmapByteUtil();
//request
HttpRequests httpRequests = new HttpRequests(Constant.APP_KEY, Constant.APP_SECRET, true, true);
Bitmap bmSmall = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
PostParameters parameters = new PostParameters();
parameters.setImg(bitmapByteUtil.bitmapToByte(bmSmall));
JSONObject jsonObject = httpRequests.detectionDetect(parameters);
Log.e("TAG", jsonObject.toString());
if(callBack!=null){
callBack.success(jsonObject);
}
} catch (FaceppParseException e) {
e.printStackTrace();
if(callBack!=null){
callBack.error(e);
}
}
}
}).start();
}
}
Log.e("TAG", jsonObject.toString());打印出的JsonObject信息,复制,百度在线jsonobject校验,黏贴,校验,可以很清晰的看到数据结构
{
"face": [
{
"attribute": {
"age": {
"range": 6,
"value": 20
},
"gender": {
"confidence": 92.9548,
"value": "Male"
},
"race": {
"confidence": 99.0418,
"value": "Asian"
},
"smiling": {
"value": 16.9204
}
},
"face_id": "5f98aef06dcf058be342dd480e1547a9",
"position": {
"center": {
"x": 56.869369,
"y": 35.25
},
"eye_left": {
"x": 54.705856,
"y": 33.151167
},
"eye_right": {
"x": 59.143694,
"y": 33.264833
},
"height": 7.5,
"mouth_left": {
"x": 54.477027,
"y": 37.124167
},
"mouth_right": {
"x": 58.912613,
"y": 37.184667
},
"nose": {
"x": 57.071622,
"y": 35.007333
},
"width": 10.135135
},
"tag": ""
}
],
"img_height": 1048,
"img_id": "01f2a35154ec947179fc5190292daac8",
"img_width": 776,
"session_id": "58dc50e81cf84c638b642c69ad79f315",
"url": null,
"response_code": 200
}
public static void detect(final Bitmap bitmap,final CallBack callBack)
该方法中的bitmap即你需要识别的图片
定义一个CallBack接口,去处理接收JsonObject数据,成功执行success,失败则执行error
由于JsonObject数据接收是在线程里面,所以我们用Handler通知外面UI进行相关操作:
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_SUCCESS:
mWaiting.setVisibility(View.GONE);
JSONObject rs = (JSONObject) msg.obj;
prepareResultBitmap(rs);
mPhoto.setImageBitmap(mBitmapPhoto);
break;
case MSG_ERROR:
mWaiting.setVisibility(View.GONE);
String errorMsg = (String) msg.obj;
if (TextUtils.isEmpty(errorMsg)) {
mTip.setText("Error.");
} else {
mTip.setText(errorMsg);
}
break;
}
}
};
FaceppDetect.detect(mBitmapPhoto, new FaceppDetect.CallBack() {
@Override
public void success(JSONObject result) {
// TODO Auto-generated method stub
Message msg = mHandler.obtainMessage(MSG_SUCCESS);
msg.obj = result;
msg.sendToTarget();
}
@Override
public void error(FaceppParseException exception) {
// TODO Auto-generated method stub
Message msg = mHandler.obtainMessage(MSG_ERROR);
msg.obj = exception.getErrorMessage();
msg.sendToTarget();
}
});
private void prepareResultBitmap(JSONObject rs) {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>Bitmap bitmap = Bitmap.createBitmap(mBitmapPhoto.getWidth(), mBitmapPhoto.getHeight(),
<span style="white-space:pre"> </span>mBitmapPhoto.getConfig());
<span style="white-space:pre"> </span>canvas = new Canvas(bitmap);
<span style="white-space:pre"> </span>canvas.drawBitmap(mBitmapPhoto, 0, 0, null);
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>JSONArray faces = rs.getJSONArray("face");
<span style="white-space:pre"> </span>int faceCount = faces.length();
<span style="white-space:pre"> </span>mTip.setText("find " + faceCount);
<span style="white-space:pre"> </span>for (int i = 0; i < faceCount; i++) {
<span style="white-space:pre"> </span>// 拿到单独face对象
<span style="white-space:pre"> </span>JSONObject face = faces.getJSONObject(i);
<span style="white-space:pre"> </span>JSONObject positonObj = face.getJSONObject("position");
<span style="white-space:pre"> </span>// get face position
<span style="white-space:pre"> </span>float x = (float) positonObj.getJSONObject("center").getDouble("x");
<span style="white-space:pre"> </span>float y = (float) positonObj.getJSONObject("center").getDouble("y");
<span style="white-space:pre"> </span>float w = (float) positonObj.getDouble("width");
<span style="white-space:pre"> </span>float h = (float) positonObj.getDouble("height");
<span style="white-space:pre"> </span>x = x / 100 * bitmap.getWidth();
<span style="white-space:pre"> </span>y = y / 100 * bitmap.getHeight();
<span style="white-space:pre"> </span>w = w / 100 * bitmap.getWidth();
<span style="white-space:pre"> </span>h = h / 100 * bitmap.getHeight();
<span style="white-space:pre"> </span>mPaint.setColor(0xffffffff);
<span style="white-space:pre"> </span>mPaint.setStrokeWidth(3);
<span style="white-space:pre"> </span>// draw box
<span style="white-space:pre"> </span>canvas.drawLine(x - w / 2, y - h / 2, x - w / 2, y + h / 2, mPaint);// 左
<span style="white-space:pre"> </span>canvas.drawLine(x - w / 2, y + h / 2, x + w / 2, y + h / 2, mPaint);// 下
<span style="white-space:pre"> </span>canvas.drawLine(x + w / 2, y + h / 2, x + w / 2, y - h / 2, mPaint);// 右
<span style="white-space:pre"> </span>canvas.drawLine(x - w / 2, y - h / 2, x + w / 2, y - h / 2, mPaint);// 上
<span style="white-space:pre"> </span>// get age and gender
<span style="white-space:pre"> </span>int age = face.getJSONObject("attribute").getJSONObject("age").getInt("value");
<span style="white-space:pre"> </span>String gender = face.getJSONObject("attribute").getJSONObject("gender").getString("value");
<span style="white-space:pre"> </span>Bitmap ageBitmap = buildAgeBitmap(age, gender.equals("Male"));
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>int ageWidth = ageBitmap.getWidth();
<span style="white-space:pre"> </span>int ageHeight = ageBitmap.getHeight();
<span style="white-space:pre"> </span>if(bitmap.getWidth()<=mPhoto.getWidth() && bitmap.getHeight()<=mPhoto.getHeight()){
<span style="white-space:pre"> </span>float ratio = Math.max(bitmap.getWidth() * 1.0f / mPhoto.getWidth(),
<span style="white-space:pre"> </span>bitmap.getHeight() * 1.0f / mPhoto.getHeight());
<span style="white-space:pre"> </span>ageBitmap = Bitmap.createScaledBitmap(ageBitmap, (int) (ageWidth * ratio),
<span style="white-space:pre"> </span>(int) (ageHeight * ratio), false);
<span style="white-space:pre"> </span>canvas.drawBitmap(ageBitmap, x - ageBitmap.getWidth() / 2, y - h / 2 - ageBitmap.getHeight(), null);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>mBitmapPhoto = bitmap;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>} catch (JSONException e) {
<span style="white-space:pre"> </span>// TODO Auto-generated catch block
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>};
<span style="white-space:pre"> </span>private Bitmap buildAgeBitmap(int age, boolean isMale) {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>TextView tv = (TextView) mWaiting.findViewById(R.id.id_age_and_gender);
<span style="white-space:pre"> </span>tv.setText(age + "");
<span style="white-space:pre"> </span>if (isMale) {
<span style="white-space:pre"> </span>tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.male), null, null, null);
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>tv.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.female), null, null, null);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>tv.setDrawingCacheEnabled(true);
<span style="white-space:pre"> </span>Bitmap bitmap = Bitmap.createBitmap(tv.getDrawingCache());
<span style="white-space:pre"> </span>tv.destroyDrawingCache();
<span style="white-space:pre"> </span>return bitmap;
<span style="white-space:pre"> </span>}
需要源码的留下你的邮箱(源码下载)