FaceView.java revision e75e33cd3de39f1961d3fac8e7a51d126260de45
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.camera.ui;
18
19import android.content.Context;
20import android.graphics.Canvas;
21import android.graphics.Matrix;
22import android.graphics.RectF;
23import android.graphics.drawable.Drawable;
24import android.hardware.Camera.Face;
25import android.util.AttributeSet;
26import android.util.Log;
27import android.view.View;
28
29import com.android.camera.R;
30import com.android.camera.Util;
31
32public class FaceView extends View implements FocusIndicator, Rotatable {
33    private final String TAG = "FaceView";
34    private final boolean LOGV = false;
35    // The value for android.hardware.Camera.setDisplayOrientation.
36    private int mDisplayOrientation;
37    // The orientation compensation for the face indicator to make it look
38    // correctly in all device orientations. Ex: if the value is 90, the
39    // indicator should be rotated 90 degrees counter-clockwise.
40    private int mOrientation;
41    private boolean mMirror;
42    private boolean mPause;
43    private Matrix mMatrix = new Matrix();
44    private RectF mRect = new RectF();
45    private Face[] mFaces;
46    private Drawable mFaceIndicator;
47    private final Drawable mDrawableFocusing;
48    private final Drawable mDrawableFocused;
49    private final Drawable mDrawableFocusFailed;
50
51    public FaceView(Context context, AttributeSet attrs) {
52        super(context, attrs);
53        mDrawableFocusing = getResources().getDrawable(R.drawable.ic_focus_focusing);
54        mDrawableFocused = getResources().getDrawable(R.drawable.ic_focus_face_focused);
55        mDrawableFocusFailed = getResources().getDrawable(R.drawable.ic_focus_failed);
56        mFaceIndicator = mDrawableFocusing;
57    }
58
59    public void setFaces(Face[] faces) {
60        if (LOGV) Log.v(TAG, "Num of faces=" + faces.length);
61        if (mPause) return;
62        mFaces = faces;
63        invalidate();
64    }
65
66    public void setDisplayOrientation(int orientation) {
67        mDisplayOrientation = orientation;
68        if (LOGV) Log.v(TAG, "mDisplayOrientation=" + orientation);
69    }
70
71    @Override
72    public void setOrientation(int orientation, boolean animation) {
73        mOrientation = orientation;
74        invalidate();
75    }
76
77    public void setMirror(boolean mirror) {
78        mMirror = mirror;
79        if (LOGV) Log.v(TAG, "mMirror=" + mirror);
80    }
81
82    public boolean faceExists() {
83        return (mFaces != null && mFaces.length > 0);
84    }
85
86    @Override
87    public void showStart() {
88        mFaceIndicator = mDrawableFocusing;
89        invalidate();
90    }
91
92    // Ignore the parameter. No autofocus animation for face detection.
93    @Override
94    public void showSuccess(boolean timeout) {
95        mFaceIndicator = mDrawableFocused;
96        invalidate();
97    }
98
99    // Ignore the parameter. No autofocus animation for face detection.
100    @Override
101    public void showFail(boolean timeout) {
102        mFaceIndicator = mDrawableFocusFailed;
103        invalidate();
104    }
105
106    @Override
107    public void clear() {
108        // Face indicator is displayed during preview. Do not clear the
109        // drawable.
110        mFaceIndicator = mDrawableFocusing;
111        mFaces = null;
112        invalidate();
113    }
114
115    public void pause() {
116        mPause = true;
117    }
118
119    public void resume() {
120        mPause = false;
121    }
122
123    @Override
124    protected void onDraw(Canvas canvas) {
125        if (mFaces != null && mFaces.length > 0) {
126            // Prepare the matrix.
127            Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, getWidth(), getHeight());
128
129            // Focus indicator is directional. Rotate the matrix and the canvas
130            // so it looks correctly in all orientations.
131            canvas.save();
132            mMatrix.postRotate(mOrientation); // postRotate is clockwise
133            canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas)
134            for (int i = 0; i < mFaces.length; i++) {
135                // Transform the coordinates.
136                mRect.set(mFaces[i].rect);
137                if (LOGV) Util.dumpRect(mRect, "Original rect");
138                mMatrix.mapRect(mRect);
139                if (LOGV) Util.dumpRect(mRect, "Transformed rect");
140
141                mFaceIndicator.setBounds(Math.round(mRect.left), Math.round(mRect.top),
142                        Math.round(mRect.right), Math.round(mRect.bottom));
143                mFaceIndicator.draw(canvas);
144            }
145            canvas.restore();
146        }
147        super.onDraw(canvas);
148    }
149}
150