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