Establecer el área de enfoque de la cámara en Android

después de varios tutoriales y ejemplos me propuse con el siguiente algoritmo para establecer el enfoque de la cámara en un punto específico, el problema es que la cámara ignora por completo el punto y realiza un enfoque general normal en lugar del área rect que he especificado. ¿Hay algo más que me falta en el algoritmo? Esto se ha probado en varios teléfonos, todos con Android 4.0 y superiores, por lo que la API de área de enfoque se admite en estos dispositivos. Tenga en cuenta que la aplicación que estoy escribiendo funciona sólo en modo horizontal.

@Override public boolean onTouchEvent(final MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { float x = event.getX(); float y = event.getY(); float touchMajor = event.getTouchMajor(); float touchMinor = event.getTouchMinor(); Rect touchRect = new Rect((int)(x - touchMajor / 2), (int)(y - touchMinor / 2), (int)(x + touchMajor / 2), (int)(y + touchMinor / 2)); this.submitFocusAreaRect(touchRect); } } private void submitFocusAreaRect(final Rect touchRect) { Camera.Parameters cameraParameters = camera.getParameters(); if (cameraParameters.getMaxNumFocusAreas() == 0) { return; } // Convert from View's width and height to +/- 1000 Rect focusArea = new Rect(); focusArea.set(touchRect.left * 2000 / cameraSurfaceView.getWidth() - 1000, touchRect.top * 2000 / cameraSurfaceView.getHeight() - 1000, touchRect.right * 2000 / cameraSurfaceView.getWidth() - 1000, touchRect.bottom * 2000 / cameraSurfaceView.getHeight() - 1000); // Submit focus area to camera ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>(); focusAreas.add(new Camera.Area(focusArea, 1000)); cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); cameraParameters.setFocusAreas(focusAreas); camera.setParameters(cameraParameters); // Start the autofocus operation camera.autoFocus(this); } 

antes de cameraParameters.setFocusAreas (focusAreas) ;, deberías agregar esto:

 cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 

este no es mi código, pero puedes probarlo. Todos los créditos van al tipo / s que hizo el ejemplo aquí Toque para seleccionar el foco y el área de medición

También contribuí a código con una línea pequeña porque cuando estaba haciendo clic en la segunda vez en la vista de superficie de la aplicación fue aplastante. Así que plese sea libre de usar la clase ("AndroidCamera") abajo:

 import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.Face; import android.hardware.Camera.FaceDetectionListener; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.ShutterCallback; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore.Images.Media; import android.view.LayoutInflater; import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.Button; import android.widget.TextView; public class AndroidCamera extends Activity implements SurfaceHolder.Callback{ Camera camera; CameraSurfaceView cameraSurfaceView; SurfaceHolder surfaceHolder; boolean previewing = false; LayoutInflater controlInflater = null; Button buttonTakePicture; TextView prompt; DrawingView drawingView; Face[] detectedFaces; final int RESULT_SAVEIMAGE = 0; private ScheduledExecutorService myScheduledExecutorService; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); getWindow().setFormat(PixelFormat.UNKNOWN); cameraSurfaceView = (CameraSurfaceView)findViewById(R.id.camerapreview); surfaceHolder = cameraSurfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); drawingView = new DrawingView(this); LayoutParams layoutParamsDrawing = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); this.addContentView(drawingView, layoutParamsDrawing); controlInflater = LayoutInflater.from(getBaseContext()); View viewControl = controlInflater.inflate(R.layout.control, null); LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); this.addContentView(viewControl, layoutParamsControl); buttonTakePicture = (Button)findViewById(R.id.takepicture); buttonTakePicture.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG); }}); /* LinearLayout layoutBackground = (LinearLayout)findViewById(R.id.background); layoutBackground.setOnClickListener(new LinearLayout.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub buttonTakePicture.setEnabled(false); camera.autoFocus(myAutoFocusCallback); }}); */ prompt = (TextView)findViewById(R.id.prompt); } public void touchFocus(final Rect tfocusRect){ buttonTakePicture.setEnabled(false); camera.stopFaceDetection(); //Convert from View's width and height to +/- 1000 final Rect targetFocusRect = new Rect( tfocusRect.left * 2000/drawingView.getWidth() - 1000, tfocusRect.top * 2000/drawingView.getHeight() - 1000, tfocusRect.right * 2000/drawingView.getWidth() - 1000, tfocusRect.bottom * 2000/drawingView.getHeight() - 1000); final List<Camera.Area> focusList = new ArrayList<Camera.Area>(); Camera.Area focusArea = new Camera.Area(targetFocusRect, 1000); focusList.add(focusArea); Parameters para = camera.getParameters(); para.setFocusAreas(focusList); para.setMeteringAreas(focusList); camera.setParameters(para); camera.autoFocus(myAutoFocusCallback); drawingView.setHaveTouch(true, tfocusRect); drawingView.invalidate(); camera.startFaceDetection(); } FaceDetectionListener faceDetectionListener = new FaceDetectionListener(){ @Override public void onFaceDetection(Face[] faces, Camera tcamera) { if (faces.length == 0){ //prompt.setText(" No Face Detected! "); drawingView.setHaveFace(false); }else{ //prompt.setText(String.valueOf(faces.length) + " Face Detected :) "); drawingView.setHaveFace(true); detectedFaces = faces; //Set the FocusAreas using the first detected face List<Camera.Area> focusList = new ArrayList<Camera.Area>(); Camera.Area firstFace = new Camera.Area(faces[0].rect, 1000); focusList.add(firstFace); Parameters para = camera.getParameters(); if(para.getMaxNumFocusAreas()>0){ para.setFocusAreas(focusList); } if(para.getMaxNumMeteringAreas()>0){ para.setMeteringAreas(focusList); } camera.setParameters(para); buttonTakePicture.setEnabled(false); //Stop further Face Detection camera.stopFaceDetection(); buttonTakePicture.setEnabled(false); /* * Allways throw java.lang.RuntimeException: autoFocus failed * if I call autoFocus(myAutoFocusCallback) here! * camera.autoFocus(myAutoFocusCallback); */ //Delay call autoFocus(myAutoFocusCallback) myScheduledExecutorService = Executors.newScheduledThreadPool(1); myScheduledExecutorService.schedule(new Runnable(){ public void run() { camera.autoFocus(myAutoFocusCallback); } }, 500, TimeUnit.MILLISECONDS); } drawingView.invalidate(); }}; AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){ @Override public void onAutoFocus(boolean arg0, Camera arg1) { // TODO Auto-generated method stub if (arg0){ buttonTakePicture.setEnabled(true); camera.cancelAutoFocus(); } float focusDistances[] = new float[3]; arg1.getParameters().getFocusDistances(focusDistances); prompt.setText("Optimal Focus Distance(meters): " + focusDistances[Camera.Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX]); }}; ShutterCallback myShutterCallback = new ShutterCallback(){ @Override public void onShutter() { // TODO Auto-generated method stub }}; PictureCallback myPictureCallback_RAW = new PictureCallback(){ @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // TODO Auto-generated method stub }}; PictureCallback myPictureCallback_JPG = new PictureCallback(){ @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // TODO Auto-generated method stub /*Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */ Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues()); OutputStream imageFileOS; try { imageFileOS = getContentResolver().openOutputStream(uriTarget); imageFileOS.write(arg0); imageFileOS.flush(); imageFileOS.close(); prompt.setText("Image saved: " + uriTarget.toString()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview(); camera.startFaceDetection(); }}; @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub if(previewing){ camera.stopFaceDetection(); camera.stopPreview(); previewing = false; } if (camera != null){ try { camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); prompt.setText(String.valueOf( "Max Face: " + camera.getParameters().getMaxNumDetectedFaces())); camera.startFaceDetection(); previewing = true; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub camera = Camera.open(); camera.setFaceDetectionListener(faceDetectionListener); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub camera.stopFaceDetection(); camera.stopPreview(); camera.release(); camera = null; previewing = false; } private class DrawingView extends View{ boolean haveFace; Paint drawingPaint; boolean haveTouch; Rect touchArea; public DrawingView(Context context) { super(context); haveFace = false; drawingPaint = new Paint(); drawingPaint.setColor(Color.GREEN); drawingPaint.setStyle(Paint.Style.STROKE); drawingPaint.setStrokeWidth(2); haveTouch = false; } public void setHaveFace(boolean h){ haveFace = h; } public void setHaveTouch(boolean t, Rect tArea){ haveTouch = t; touchArea = tArea; } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub if(haveFace){ // Camera driver coordinates range from (-1000, -1000) to (1000, 1000). // UI coordinates range from (0, 0) to (width, height). int vWidth = getWidth(); int vHeight = getHeight(); for(int i=0; i<detectedFaces.length; i++){ if(i == 0){ drawingPaint.setColor(Color.GREEN); }else{ drawingPaint.setColor(Color.RED); } int l = detectedFaces[i].rect.left; int t = detectedFaces[i].rect.top; int r = detectedFaces[i].rect.right; int b = detectedFaces[i].rect.bottom; int left = (l+1000) * vWidth/2000; int top = (t+1000) * vHeight/2000; int right = (r+1000) * vWidth/2000; int bottom = (b+1000) * vHeight/2000; canvas.drawRect( left, top, right, bottom, drawingPaint); } }else{ canvas.drawColor(Color.TRANSPARENT); } if(haveTouch){ drawingPaint.setColor(Color.BLUE); canvas.drawRect( touchArea.left, touchArea.top, touchArea.right, touchArea.bottom, drawingPaint); } } } } 

Todo lo que hice fue añadir camera.startFaceDetection(); después de drawingView.invalidate();

PS En ese sitio es un enlace para descargar todo el proyecto!

  • Manejo de enfoque personalizado de ViewGroup
  • ListView en SlidingDrawer pierde foco después de onResume
  • Cómo deshabilitar / modificar AutoFocus y AutoWhiteBalance en Android Camera usando OpenCV
  • EditText: Evita concentrarte en setText ()
  • Desplazamiento en Horizontal ScrollView pierde el foco del elemento enfocado,
  • Solicitar enfocar en editar texto
  • El teclado androide no aparece en el enfoque de llamada en el campo de texto sencha
  • Android onfocuschange en xml
  • SearchView quita la línea de enfoque azul y muestra el cursor en determinada posición
  • Navegación permanenteVerifique el enfoque suelto después de seleccionar un elemento
  • Cómo hacer edittext autofocus después de mostrar un brindis?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.