App层focus or face detection界面显示分析
Android应用的重要工作就是更新界面显示,在camera应用中也不例外, 观察目录结构,发现ui相关的类和接口保存在src/com/android/camera/ui 文件夹下,在使用相机时我们发现无论是对焦还是人脸识别他们的相关界面是极其相似的,究其原因是在代码实现的过程中利用了面向对象的重要性质-----多态。
代码分析:
首先界面更新调用了FocusManager.java中的updateFocusUI()方法。
public void updateFocusUI() {
if (!mInitialized) return;
// Set the length of focus indicator according to preview frame size.
int len = Math.min(mPreviewFrame.getWidth(), mPreviewFrame.getHeight()) / 4;
ViewGroup.LayoutParams layout = mFocusIndicator.getLayoutParams();
layout.width = len;
layout.height = len;
// Show only focus indicator or face indicator.
boolean faceExists = (mFaceView != null && mFaceView.faceExists());
FocusIndicator focusIndicator = (faceExists) ? mFaceView : mFocusIndicator;
if (mState == STATE_IDLE) {
if (mFocusArea == null) {
focusIndicator.clear();
} else {
// Users touch on the preview and the indicator represents the
// metering area. Either focus area is not supported or
// autoFocus call is not required.
focusIndicator.showStart();
}
} else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
focusIndicator.showStart();
} else {
if (mState == STATE_SUCCESS) {
focusIndicator.showSuccess();
} else if (mState == STATE_FAIL) {
focusIndicator.showFail();
}
}
}
多态实现代码用绿色表示,根据代码FaceView,FocusIndicatorView 都继承了FocusIndicator接口,而实际上此接口就定义了显示规范。
public class FaceView extends View implements FocusIndicator, Rotatable {
public class FocusIndicatorView extends View implements FocusIndicator {
public inte易做图ce FocusIndicator {
public void showStart();
public void showSuccess();
public void showFail();
public void clear();
}
另一方面,FaceView,FocusIndicatorView在显示中还有细微不同,最重要的是FaceView可以识别多个人脸,显示多个识别框。这个功能是通过重写view的onDraw(Canvas canvas)方法实现的。
代码分析:
@Override
protected void onDraw(Canvas canvas) {
if (mFaces != null && mFaces.length > 0) {
// Prepare the matrix.
Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, getWidth(), getHeight());
// Focus indicator is directional. Rotate the matrix and the canvas
// so it looks correctly in all orientations.
canvas.save();
mMatrix.postRotate(mOrientation); // postRotate is clockwise
canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas)
for (int i = 0; i < mFaces.length; i++) {
// Transform the coordinates.
mRect.set(mFaces[i].rect);
if (LOGV) Util.dumpRect(mRect, "Original rect");
mMatrix.mapRect(mRect);
if (LOGV) Util.dumpRect(mRect, "Transformed rect");
mFaceIndicator.setBounds(Math.round(mRect.left), Math.round(mRect.top),
Math.round(mRect.right), Math.round(mRect.bottom));
mFaceIndicator.draw(canvas);
}
canvas.restore();
}
super.onDraw(canvas);
}
}
绿色部分是通过遍历face数组画出每个人脸所对应的识别框。
作者:cibon
补充:移动开发 , Android ,