1.腾讯优图的开发者申请,通过QQ号登陆并绑定邮箱后,在应用管理中查看申请得到的AppID,SecretID以及SecretKey。
2.通过http进行请求发送时,都需要在请求头中添加对应信息。对签名进行的算法在相关sdk中有具体实现。
通过StringBuffer存储算法实现过程中生成的sign值。在sdk的Youtu.java中有具体样例代码。
3.将com.youtu和com.youtu.sign中的相关代码复制到自己的项目中。
在进行图片的识别时,首先要定义新建Youtu对象所需要的相关参数。
新建Youtu对象并填入相关参数
Youtu faceYoutu = new Youtu(APP_ID, SECRET_ID, SECRET_KEY, Youtu.API_YOUTU_END_POINT);
之后就可以调用Youtu对象进行图像的识别或对比了。
4.比较两张图片的相关代码
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
TextView tv = (TextView) findViewById(R.id.tv_res);
tv.setText(msg.obj.toString());
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView img = (ImageView) findViewById(R.id.img_pic1);
ImageView img2 = (ImageView) findViewById(R.id.img_pic2);
img.setImageResource(R.drawable.a);
img2.setImageResource(R.drawable.b);
new Thread() {
public void run() {
Youtu faceYoutu = new Youtu(APP_ID, SECRET_ID, SECRET_KEY, Youtu.API_YOUTU_END_POINT);
Bitmap bitmapA = BitmapFactory.decodeResource(getResources(), R.drawable.a);
Bitmap bitmapB = BitmapFactory.decodeResource(getResources(), R.drawable.b);
JSONObject respose;
try {
respose = faceYoutu.FaceCompare(bitmapA, bitmapB);
Message msg = new Message();
msg.obj = respose;
handler.sendMessage(msg);
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
};
}.start();
}
这里返回的json数据中的similarity就是两张人脸的相似度了。
需要实现实时的拍照进行照片与图片的对比,首先需要预览照相机,通过使用surfaceView进行预览图的显示。Activity实现SurfaceHolder.Callback的接口并实现相应的方法。
surfaceView与surfaceViewHolder的初始化:
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
mSurfaceView.setFocusable(true);
mSurfaceView.setFocusableInTouchMode(true);
mSurfaceView.setClickable(true);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
// 设置该SurfaceView是一个"推送"类型的SurfaceView
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(this);
重写实现接口相应的方法。分别是在surfaceView创建时,改变属性时,销毁时相应的操作。
在surfaceView创建时进行Camera的初始化,通过Camera的open()开启摄像头,当参数为1时开启前置摄像头。因为摄像头显示的预览界面可能方向是横着的,可以通过setDisplayOrientation(90);进行预览界面的偏移。设置好相关参数后,就可以开始预览camera的画面了,当销毁时停止预览并释放资源。
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open(1);
Camera.Parameters parameters = mCamera.getParameters();
try {
// 将摄像头的预览显示设置为mSurfaceHolder
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.setDisplayOrientation(90);
} catch (IOException e) {
mCamera.release();
}
// 设置输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
// 设置摄像头的参数.否则前面的设置无效
mCamera.setParameters(parameters);
// 摄像头开始预览
mCamera.startPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
因为第一次使用surfaceView不是很明白如何使surfaceView形状改变时,相机的预览画面不发生挤压,比如surfaceview是正方形时在正方形中显示与全屏状态下等比例的画面。所以我的surfaceView大小还是设置的几乎全屏,不过通过下方显示图片区域设置可点击,使surfaceview只能在显示区域进行点击拍照。点击事件调用拍照的代码:mCamera.takePicture(null, null, this);
希望各位告知如何实现改变surfaceview的大小,不改变预览图形状。
实现Camera.PictureCallback接口可以在拍照后进行回调onPictureTaken(byte[] data, Camera camera)方法。
最开始在拍摄照片后进行对比时时间很长,几乎10s左右,看了很久才明白Bitmap图片太大了,所以在进行比较前需要对bitmap对象进行一次压缩。onPictureTaken的实现代码如下,经过图片压缩之后,解析速度保持在3s左右。
@Override
public void onPictureTaken(byte[] data, Camera camera) {
ImageView img = (ImageView) findViewById(R.id.img_pic1);
// 将图片保存至相册
// ContentResolver resolver = getContentResolver();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix m = new Matrix();
m.setRotate(-90);
bitA = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
bitA = Bitmap.createScaledBitmap(bitA, bitA.getWidth()/5, bitA.getHeight()/5, true);
img.setImageBitmap(bitA);
new CompareTask().execute(bitA, bitB);
// MediaStore.Images.Media.insertImage(resolver, bitmap, "t", "des");
// 拍照后重新开始预览
camera.startPreview();
bitmap.recycle();
}
相关xml代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.yoututest.MainActivity" >
<TextView
android:id="@+id/tv_res"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<SurfaceView
android:id="@+id/surfaceView"
android:layout_below="@id/tv_res"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/ll"
android:background="@android:color/white"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="150dp"
android:clickable="true"
android:orientation="horizontal" >
<ImageView
android:id="@+id/img_pic1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:scaleType="centerInside" />
<ImageView
android:id="@+id/img_pic2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:scaleType="center" />
</LinearLayout>
</RelativeLayout>
上方显示相机预览,下方左边是拍照后的预览图,右边是对比图。后续进行图片地址的设置啥啥啥的再看吧。