2016-04-16 2 views
1

Я разрабатываю приложение для Android, которое позволяет пользователю проверять содержимое QR-кода и выполнять что-то по результату чтения.Создать на клик фокус на CameraSource - Android QR Code detection

В целях повышения производительности я хотел бы реализовать 2 метода:

  • onClickFocus (что позволяет пользователю сосредоточиться на камеру, когда экран будет нажата)
  • TURNON/OFF вспышка (которая позволяет пользователю для включения/выключения вспышки)

я сделал некоторое рытье и выяснил, что для управления камерой и вспышкой я должен быть в состоянии управлять Camera, как и сам объект.

И вот здесь начинается кошмар.

Я использую следующий код, чтобы показать результат камеры и отслеживать QR-коды.

import android.app.FragmentTransaction; 
import android.content.Context; 


import android.os.Bundle; 
import android.os.Vibrator; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.util.SparseArray; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.widget.TextView; 

import com.google.android.gms.vision.Detector; 
import com.google.android.gms.vision.barcode.Barcode; 
import com.google.android.gms.vision.barcode.BarcodeDetector; 
import java.io.IOException; 



public class MainReadActivity extends AppCompatActivity { 


    public SurfaceView cameraView; 
    private TextView barcodeInfo; 
    public BarcodeDetector barcodeDetector; 
    public CameraSource cameraSource; 
    public Vibrator v; 
    public String textInfo; 
    public DrawerLayout mDrawerLayout; 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_read); 
     v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 

     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout_main); 


     getSupportFragmentManager().findFragmentById(R.id.drawer_layout_main); 

     cameraView = (SurfaceView) findViewById(R.id.camera_view); 


     //barcodeInfo = (TextView) findViewById(R.id.code_info); 

     barcodeDetector = new BarcodeDetector.Builder(this) 
       .setBarcodeFormats(Barcode.QR_CODE) 
       .build(); 


     cameraSource = new CameraSource.Builder(this, barcodeDetector).build(); 



     cameraView.getHolder().addCallback(new SurfaceHolder.Callback() { 

      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 


       try { 
        cameraSource.start(cameraView.getHolder()); 
       } catch (IOException ie) { 
        Log.e("CAMERA SOURCE", ie.getMessage()); 
       } 

      } 


      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
       cameraSource.stop(); 
      } 

     }); 


     barcodeDetector.setProcessor(new Detector.Processor<Barcode>() { 

      @Override 
      public void release() { 

      } 


      @Override 
      public void receiveDetections(Detector.Detections<Barcode> detections) { 
       final SparseArray<Barcode> barcodes = detections.getDetectedItems(); 

       if (barcodes.size() != 0) { 


        new Runnable() { // Use the post method of the TextView 
         public void run() { 


          v.vibrate(500); 
          // textInfo = barcodes.valueAt(0).displayValue; 

          MyFragmentDialog newf = new MyFragmentDialog(); 
          FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
          transaction.replace(R.id.fragment_container, newf); 

          transaction.addToBackStack("tag"); 
          transaction.commit(); 

         } 
        }; 
       } 
      } 

     }); 







    } 

    public void onBackPressed() { 
     // do nothing 
    } 
} 

Итак, мне нужно, чтобы получить доступ к камере, от CameraSource (я прав ?!) После того, как это не возможно, я судимый использовать этот CameraSource класс от мерзавца GoogleSamples, который позволяет использовать метод setFocusMode. .. Но, к сожалению, я не увенчался успехом.

Я также попытался использовать API 21, поскольку API 22 no longer supports Camera and CameraPreferences.

Я уверен, что это не только моя проблема, но и не удалось найти способ ее исправить.

Любой может помочь?

ИСПРАВЛЕНО:

Просто используйте этот CameraSource (github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms /samples/vision/barcodereader/ui/camera/CameraSource.java). Да, я знаю, я предложил ... Но на этот раз я исправил свою проблему! Так что, если вы собираетесь использовать это, убедитесь, что ваша компиляция выглядит следующим образом:

compile 'com.google.android.gms:play-services:8.1.0' 

ответ

0

Ответ здесь: Google Vision API Samples: Get the CameraSource to Focus

Для использования автоматической фокусировки .setAutoFocusEnabled(true) на ваш CameraSource.Builder()

+0

Я старался. В результате «невозможно разрешить метод .setAutoFocusEnabled (boolean)» –

1

Инициализировать эти и определить их в OnCreate

 Camera.Parameters params; 
    Camera camera; 
    CameraSource cameraSource; 
    SurfaceView cameraView; 
    boolean isFlash = false; 

вызова changeFlashStatus() метод, чтобы включить вспышку и назовите его снова, чтобы включить вспышку OFF

public void changeFlashStatus() { 


        Field[] declaredFields = CameraSource.class.getDeclaredFields(); 

        for (Field field : declaredFields) { 
         if (field.getType() == Camera.class) { 
          field.setAccessible(true); 
          try { 
           camera = (Camera) field.get(cameraSource); 
           if (camera != null) { 
            params = camera.getParameters(); 

            if(!isFlash){ 
             params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
             flashImage.setColorFilter(getResources().getColor(R.color.yellow)); 
             isFlash = true; 
            } else { 
             params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
             flashImage.setColorFilter(getResources().getColor(R.color.greyLight)); 
             isFlash = false; 

            } 
            camera.setParameters(params); 

           } 

          } catch (IllegalAccessException e) { 
           e.printStackTrace(); 
          } 

          break; 
         } 
        } 

       } 
      }); 

     } 

Чтобы получить камеру для фокусировки необходимо конкретную область (Rect), чтобы передать его в камеру, чтобы сосредоточиться на этой области.Поэтому мы должны реализовать onTouchListener() для surfaceView, поэтому, когда мы касаемся surfaceView, мы создаем MotionEvent, который определяет, где именно вы касаетесь surfaceView, затем мы можем извлечь Rect из MotionEvent.

Звоните initCameraFocusListener() в ваш OnCreate. Безопасно Назовите его после начала работы камеры

private void initCameraFocusListener() { 
     cameraView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 

       cameraFocus(event, cameraSource, Camera.Parameters.FOCUS_MODE_AUTO); 

       return false; 
      } 
     }); 

    } 





private boolean cameraFocus(MotionEvent event, @NonNull CameraSource cameraSource, @NonNull String focusMode) { 
     Field[] declaredFields = CameraSource.class.getDeclaredFields(); 


     int pointerId = event.getPointerId(0); 
     int pointerIndex = event.findPointerIndex(pointerId); 
     // Get the pointer's current position 
     float x = event.getX(pointerIndex); 
     float y = event.getY(pointerIndex); 

     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)); 

     Rect focusArea = new Rect(); 

     focusArea.set(touchRect.left * 2000/cameraView.getWidth() - 1000, 
       touchRect.top * 2000/cameraView.getHeight() - 1000, 
       touchRect.right * 2000/cameraView.getWidth() - 1000, 
       touchRect.bottom * 2000/cameraView.getHeight() - 1000); 

     // Submit focus area to camera 

     ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>(); 
     focusAreas.add(new Camera.Area(focusArea, 1000)); 

     for (Field field : declaredFields) { 
      if (field.getType() == Camera.class) { 
       field.setAccessible(true); 
       try { 
        camera = (Camera) field.get(cameraSource); 
        if (camera != null) { 
         params = camera.getParameters(); 
         params.setFocusMode(focusMode); 
         params.setFocusAreas(focusAreas); 
         camera.setParameters(params); 

         // Start the autofocus operation 

         camera.autoFocus(new Camera.AutoFocusCallback() { 
          @Override 
          public void onAutoFocus(boolean b, Camera camera) { 
           // currently set to auto-focus on single touch 
          } 
         }); 
         return true; 
        } 

        return false; 
       } catch (IllegalAccessException e) { 
        e.printStackTrace(); 
       } 

       break; 
      } 
     } 



     return false; 
    }