1 /* 2 * Copyright (C) 2015 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 17 package com.android.example.rscamera; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.hardware.camera2.CameraAccessException; 22 import android.hardware.camera2.CameraCaptureSession; 23 import android.hardware.camera2.CameraManager; 24 import android.hardware.camera2.CaptureRequest; 25 import android.hardware.camera2.TotalCaptureResult; 26 import android.renderscript.RenderScript; 27 import android.util.AttributeSet; 28 import android.util.Log; 29 import android.util.Size; 30 import android.view.MotionEvent; 31 import android.view.Surface; 32 import android.view.SurfaceHolder; 33 import android.view.View; 34 35 import com.android.example.rscamera.rscamera.R; 36 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** 41 * Created by hoford on 2/27/15. 42 */ 43 public class CameraView extends FixedAspectSurfaceView { 44 private static final String TAG = "CameraPreView"; 45 46 private static final long MICRO_SECOND = 1000; 47 private static final long MILLI_SECOND = MICRO_SECOND * 1000; 48 private static final long ONE_SECOND = MILLI_SECOND * 1000; 49 50 private Surface mPreviewSurface; 51 ViewfinderProcessor mProcessor; 52 private Surface mProcessingNormalSurface; 53 CameraOps mCameraOps; 54 CameraManager mCameraManager; 55 Activity mActivity; 56 Context mContext; 57 byte mode = 0; 58 public static final byte MODE_NONE = 0; 59 public static final byte MODE_SPEED = 1; 60 public static final byte MODE_FOCUS = 2; 61 public static final byte MODE_ISO = 3; 62 RenderScript mRS; 63 ErrorCallback mErrorCallback; 64 ParametersChangedCallback mParametersChangedCallback; 65 CameraView(Context context, AttributeSet attrs)66 public CameraView(Context context, AttributeSet attrs) { 67 super(context, attrs); 68 mContext = context; 69 70 mRS = RenderScript.create(mContext); 71 SurfaceHolder.Callback callback = new SurfaceHolder.Callback() { 72 @Override 73 public void surfaceCreated(SurfaceHolder holder) { 74 } 75 76 @Override 77 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 78 mPreviewSurface = holder.getSurface(); 79 setupProcessor(); 80 } 81 82 @Override 83 public void surfaceDestroyed(SurfaceHolder holder) { 84 mPreviewSurface = null; 85 } 86 }; 87 getHolder().addCallback(callback); 88 mCameraManager = (CameraManager) mContext.getSystemService(mContext.CAMERA_SERVICE); 89 90 CameraOps.ErrorDisplayer errorDisplayer = new CameraOps.ErrorDisplayer() { 91 92 @Override 93 public void showErrorDialog(String errorMessage) { 94 Log.v(TAG, "ERROR"); 95 if (mErrorCallback != null) { 96 mErrorCallback.showError(errorMessage); 97 } 98 //MessageDialogFragment.newInstance(errorMessage).show(getFragmentManager(), FRAGMENT_DIALOG); 99 } 100 101 @Override 102 public String getErrorString(CameraAccessException e) { 103 switch (e.getReason()) { 104 case CameraAccessException.CAMERA_DISABLED: 105 return mContext.getString(R.string.camera_disabled); 106 case CameraAccessException.CAMERA_DISCONNECTED: 107 return mContext.getString(R.string.camera_disconnected); 108 case CameraAccessException.CAMERA_ERROR: 109 return mContext.getString(R.string.camera_error); 110 default: 111 return mContext.getString(R.string.camera_unknown, e.getReason()); 112 113 } 114 } 115 }; 116 117 CameraOps.CameraReadyListener cameraReadyListener = new CameraOps.CameraReadyListener() { 118 @Override 119 public void onCameraReady() { 120 mCameraOps.setUpCamera(mProcessingNormalSurface); 121 } 122 }; 123 setOnTouchListener(new View.OnTouchListener() { 124 @Override 125 public boolean onTouch(View v, MotionEvent event) { 126 return touchScreen(event); 127 } 128 }); 129 mCameraOps = new CameraOps(mCameraManager, 130 errorDisplayer, 131 cameraReadyListener); 132 } 133 resume(Activity activity)134 public void resume(Activity activity) { 135 mActivity = activity; 136 137 String errorMessage = mCameraOps.resume(); 138 if (errorMessage != null) { 139 if (mErrorCallback != null) { 140 mErrorCallback.showError(errorMessage); 141 } 142 } else { 143 144 Size outputSize = mCameraOps.getBestSize(); 145 mProcessor = new ViewfinderProcessor(mRS, outputSize); 146 // Configure the output view - this will fire surfaceChanged 147 setAspectRatio((float) outputSize.getWidth() / outputSize.getHeight()); 148 getHolder().setFixedSize(outputSize.getWidth(), outputSize.getHeight()); 149 } 150 } 151 pause()152 public void pause() { 153 mCameraOps.pause(); 154 } 155 156 /** 157 * Once camera is open and output surfaces are ready, configure the RS processing 158 * and the camera device inputs/outputs. 159 */ setupProcessor()160 private void setupProcessor() { 161 if (mProcessor == null || mPreviewSurface == null) return; 162 mProcessor.setOutputSurface(mPreviewSurface); 163 mProcessingNormalSurface = mProcessor.getInputSurface(); 164 mCameraOps.setSurface(mProcessingNormalSurface); 165 } 166 takePicture()167 public void takePicture() { 168 // Orientation 169 int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); 170 int jpegRotation = Surface.ROTATION_0; 171 switch (rotation) { 172 case 90: 173 jpegRotation = Surface.ROTATION_0; 174 break; 175 case 0: 176 jpegRotation = Surface.ROTATION_90; 177 break; 178 case 180: 179 jpegRotation = Surface.ROTATION_270; 180 break; 181 case 270: 182 jpegRotation = Surface.ROTATION_180; 183 break; 184 } 185 String name = "Simple" + System.currentTimeMillis() + ".jpg"; 186 mCameraOps.captureStillPicture(jpegRotation, name, mContext.getContentResolver()); 187 } 188 189 private CameraCaptureSession.CaptureCallback mPhotoCallback 190 = new CameraCaptureSession.CaptureCallback() { 191 192 public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 193 TotalCaptureResult result) { 194 Log.v(TAG, "onCaptureCompleted " + result.toString()); 195 } 196 }; 197 198 float mDownY; 199 long mExposureDown; 200 float mFocusDistDown; 201 touchScreen(MotionEvent event)202 public boolean touchScreen(MotionEvent event) { 203 if (event.getAction() == MotionEvent.ACTION_DOWN) { 204 mDownY = event.getY(); 205 mExposureDown = mCameraOps.getExposure(); 206 mFocusDistDown = mCameraOps.getFocusDistance(); 207 if (mFocusDistDown == 0.0) { 208 mFocusDistDown = 0.01f; 209 } 210 } 211 float distanceY = event.getY() - mDownY; 212 float width = getWidth(); 213 float height = getHeight(); 214 215 float yDistNorm = distanceY / height; 216 217 float ACCELERATION_FACTOR = 8; 218 float scaleFactor = (float) Math.pow(2.f, yDistNorm * ACCELERATION_FACTOR); 219 220 switch (mode) { 221 case MODE_SPEED: 222 long exp = (long) (mExposureDown * scaleFactor); 223 exp = Math.min(mCameraOps.getExpMax(), exp); 224 mCameraOps.setExposure(Math.max(mCameraOps.getExpMin(), exp)); 225 Log.v(TAG, "mExposure =" + mCameraOps.getExposure()); 226 break; 227 case MODE_FOCUS: 228 float focusDist = mFocusDistDown * scaleFactor; 229 focusDist = Math.max(0.0f, Math.min(mCameraOps.getFocusMin(), focusDist)); 230 if (focusDist < 0.01) focusDist = 0; 231 mCameraOps.setFocusDistance(focusDist); 232 Log.v(TAG, "mFocusDist =" + focusDist); 233 break; 234 case MODE_ISO: 235 ACCELERATION_FACTOR = 2; 236 scaleFactor = (float) Math.pow(2.f, yDistNorm * ACCELERATION_FACTOR); 237 int iso = (int) (getIso() * scaleFactor); 238 iso = Math.min(mCameraOps.getIsoMax(), iso); 239 mCameraOps.setIso(Math.max(mCameraOps.getIsoMin(), iso)); 240 break; 241 } 242 243 if (mParametersChangedCallback != null) { 244 mParametersChangedCallback.parametersChanged(); 245 } 246 mCameraOps.setParameters(); 247 248 return true; 249 } 250 setMode(byte mode)251 public void setMode(byte mode) { 252 this.mode = mode; 253 } 254 getMode()255 public byte getMode() { 256 return mode; 257 } 258 getIso()259 public int getIso() { 260 return mCameraOps.getIso(); 261 } 262 setIso(int iso)263 public void setIso(int iso) { 264 mCameraOps.setIso(iso); 265 if (mParametersChangedCallback != null) { 266 mParametersChangedCallback.parametersChanged(); 267 } 268 mCameraOps.setParameters(); 269 } 270 getExposure()271 public long getExposure() { 272 return mCameraOps.getExposure(); 273 } 274 setExposure(long exposure)275 public void setExposure(long exposure) { 276 mCameraOps.setExposure(exposure); 277 if (mParametersChangedCallback != null) { 278 mParametersChangedCallback.parametersChanged(); 279 } 280 mCameraOps.setParameters(); 281 } 282 getFocusDist()283 public float getFocusDist() { 284 return mCameraOps.getFocusDistance(); 285 } 286 setFocusInMeters(float dist)287 public void setFocusInMeters(float dist) { 288 float min = mCameraOps.getFocusMin(); 289 float d = 10 / (dist + 10 / min); 290 setFocusDist(d); 291 } 292 setFocusDist(float dist)293 public void setFocusDist(float dist) { 294 mCameraOps.setFocusDistance(dist); 295 mCameraOps.setParameters(); 296 } 297 getMinFocusDistance()298 public float getMinFocusDistance() { 299 return mCameraOps.getFocusMin(); 300 } 301 setAutofocus(boolean autofocus)302 public void setAutofocus(boolean autofocus) { 303 mCameraOps.setAutoFocus(autofocus); 304 mCameraOps.setParameters(); 305 } 306 isAutoExposure()307 public boolean isAutoExposure() { 308 return mCameraOps.isAutoExposure(); 309 } 310 isAutofocus()311 public boolean isAutofocus() { 312 return mCameraOps.isAutoFocus(); 313 } 314 setAutoExposure(boolean autoExposure)315 public void setAutoExposure(boolean autoExposure) { 316 mCameraOps.setAutoExposure(autoExposure); 317 mCameraOps.setParameters(); 318 } 319 320 public static interface ErrorCallback { showError(String errorMessage)321 public void showError(String errorMessage); 322 } 323 setErrorCallback(ErrorCallback errorCallback)324 public void setErrorCallback(ErrorCallback errorCallback) { 325 mErrorCallback = errorCallback; 326 } 327 328 public static interface ParametersChangedCallback { parametersChanged()329 public void parametersChanged(); 330 } 331 setParametersChangedCallback(ParametersChangedCallback parametersChangedCallback)332 public void setParametersChangedCallback(ParametersChangedCallback parametersChangedCallback) { 333 mParametersChangedCallback = parametersChangedCallback; 334 } 335 getFps()336 float getFps() { 337 return mProcessor.getmFps(); 338 } 339 } 340