2013-04-10 3 views
0

У меня есть пользовательская активность камеры OpenCV, которая снимает фотографию при нажатии экрана. Активность начинается с намерения startActivityForResult, и путь к файлу возвращается в MainActivity после завершения операции. Однако камера сохраняет фото асинхронно, и поэтому путь к файлу не должен проверяться до тех пор, пока не будет сделана фотография. Я использую путь к файлу для установки imageView, и его вызов сразу дает пустое изображение. Мне удалось заставить его работать, используя Thread.sleep(3000);, но это ужасный вариант, поскольку он просто закрывает пользовательский интерфейс, который, как я читал бесчисленное количество раз, является большим, нет, нет! Есть ли способ, который я могу подождать, пока фотография не будет сохранена, прежде чем вызвать возврат к MainActivity намерениям? Я понимаю, что есть обратный вызов с камеры, но я не понимаю, как это работает или как его использовать, возможно, это лучший способ пойти?Ожидание камеры для сохранения фотографии, что лучше, чем thread.sleep?

Вот какой-то код.

в MainActivity extends FragmentActivity:

rootView.findViewById(R.id.button_start_camera).setOnClickListener(new View.OnClickListener() { 
       // Listen for Take Photo button Click, start app's openCV camera 
       @Override 
       public void onClick(View view) { 
        // Start Camera app 
        Intent intentCamera = new Intent(getActivity(), CameraActivity.class); 
        startActivityForResult(intentCamera, 2); 
       } 
      }); 

В CameraActivity extends Activity implements CvCameraViewListener2, OnTouchListener:

@Override 
    public boolean onTouch(View v, MotionEvent event) { 
     Log.i(TAG,"onTouch event"); 
     if (takePicture) { 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss"); 
      String currentDateandTime = sdf.format(new Date()); 
      fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() + 
        "/MatCom_" + currentDateandTime + ".jpg"; 
      mOpenCvCameraView.takePicture(fileName); 
      Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show(); 
      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      Intent returnIntent = new Intent(); 
      returnIntent.putExtra("result", fileName); 
      setResult(RESULT_OK, returnIntent); 
      finish(); 
     } 
      return false; 
    } 

А потом обратно MainActivity:

@Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) 
    { 
     super.onActivityResult(requestCode, resultCode, intent); 
     Log.i(TAG, "onActivityResult. resultCode = " + requestCode); 
     if (requestCode == 1) {//My other startActivityForResult...} 

     if (requestCode == 131074 && resultCode == RESULT_OK){ 
      Bundle bundle = intent.getExtras(); 
      filepath = bundle.getString("result"); 
      Log.i(TAG, filepath); 
      imageView = (ImageView) findViewById(R.id.imageView); 
      bmp = BitmapFactory.decodeFile(filepath); 
      imageView.setBackgroundResource(0); 
      imageView.setImageBitmap(bmp); 
     } 
    } 

УВЕДОМЛЕНИЕ: Как и в сторону, по какой-то причине мой requestCode возвращается как 131074 каждый раз, несмотря на установку его на 2 для startActivityForResult - сообщите мне, знаете ли вы, почему это так.

Наконец, в случае, если это необходимо, чтобы видеть, вот takePicture метод из класса CameraView:

public void takePicture(final String fileName) { 
     Log.i(TAG, "Taking picture"); 
     PictureCallback callback = new PictureCallback() { 

      private String mPictureFileName = fileName; 

      @Override 
      public void onPictureTaken(byte[] data, Camera camera) { 
       Log.i(TAG, "Saving a bitmap to file"); 
       Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length); 
       try { 
        FileOutputStream out = new FileOutputStream(mPictureFileName); 
        picture.compress(Bitmap.CompressFormat.JPEG, 90, out); 
        picture.recycle(); 

        // Open the image for analysis 


        // Read in the image from the file 
        Mat mOriginalImage = Highgui.imread(fileName); 

        // Only process the image if it actually exists! 
        if (mOriginalImage != null) { 

         // Find the size of the image 
         org.opencv.core.Size mSizeReadImage = mOriginalImage.size(); 

         // From the number of rows and columns get the coordinates of the largest possible centralised square 
         double height = mSizeReadImage.height; 
         double width = mSizeReadImage.width; 
         double minDim = Math.min(height, width); 
         double top = height/2.0 - 2.0*minDim/5.0; 
         double left = width/2.0 - 2.0*minDim/5.0; 

         // Create a submat of the image based on the centralised square 
         Mat mOriginalImageSubmat = mOriginalImage.submat((int)Math.round(top), (int)Math.round(top + 4.0*minDim/5.0), (int)Math.round(left), (int)Math.round(left + 4.0*minDim/5.0)); 

         // Create another Mat the required size but same type as mOriginalImageSubmat and resize mOriginalImageSubmat to fit into it 
         Mat mDrawableSubmat = new Mat(new Size(480.0, 480.0), mOriginalImageSubmat.type()); 
         Imgproc.resize(mOriginalImageSubmat, mDrawableSubmat, mDrawableSubmat.size()); 

         Mat mColourSourceSubmat = mDrawableSubmat.clone(); 
         Mat mCannyOutput = mDrawableSubmat.clone(); 

         double minLineLength = 300.0; 

         ColourMatrix matrix = new ColourMatrix(); 

         matrix.setColourMatch(colourMatch); 
         matrix.setColourOrder(colourOrder); 
         matrix.setComparison(comparison); 
         matrix.setDisplayHotspots(displayHotspots); 
         matrix.setDisplayOutline(displayOutline); 
         matrix.setIntensity(intensity); 
         matrix.setMatrixType(matrixType); 

         String output = matrix.decode(mColourSourceSubmat, mCannyOutput, mDrawableSubmat, minLineLength); 
         Log.i(TAG, "DJH - decoded: " + output); 
        } 

        mCamera.startPreview(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     mCamera.takePicture(null, null, callback); 
    } 
+0

Вы уже выяснили, почему resultCode всегда 131074? У меня такой же resultCode и интересно, почему это происходит. Фактически resultCode является (131073 + originalResultCode). Поэтому, если я установил свой resultCode на 3 вместо 2, тогда Android даст мне 131075 ... Не могли бы вы проверить, является ли это зависимым от устройства значением? – muetzenflo

+2

Привет, просто нашел решение здесь: http://stackoverflow.com/questions/13659796/why-am-i-getting-wrong-requestcode Звонок getActivity(). StartActvitiyForResult() вместо startActivityForResult() – muetzenflo

ответ

0

Thread.sleep не плохо само по себе. Вы можете использовать цикл до 30 с thread.sleep(100). Тогда вы будете останавливаться только на 1 секунду, а процессор все еще не будет всплескиваться.

+0

Я не знаю «Не знаю, что вы имеете в виду с« application.doevents », быстрый google предполагает, что это не функция Java, и как это мне помогает? – David

+0

К сожалению, я просто взглянул на код, так что точки с запятой, и предположим, что C#. В любом случае, если вы разложите функцию сна на более мелкие части, это должно помочь. Я исправлю ответ. – xpda

+0

Почему это поможет? Меня больше волнует тот факт, что я просто шлепаю слепой лабиринт в пользовательском интерфейсе, а не заканчиваю деятельность, когда другой выполнил ее задачу. – David