2017-12-17 7 views
1

私は写真を撮ったり保存したりできるJavaCameraViewサブクラスを持っています。問題は、onCameraFrame()で受信したプレビューフレームが、キャプチャされ保存された写真と同じディメンションを共有しないため、保存されたイメージがフレームに対してクロップして表示されることです。入力フレームは1080 * 1440(3:4)で、キャプチャは2988 * 5312(9:16)です。次のようにAndroid、OpenCv、取り込まれた写真の寸法がプレビューと一致しません

私のコードは次のとおりです。他のクラスにおいては

public void takePicture() { 
    Log.i(CaptureActivity.TAG, "MyCameraView, takePicture()"); 
    // Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture. 
    // Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue 
    mCamera.setPreviewCallback(null); 

    // PictureTakenListener is implemented by the current class 
    mCamera.takePicture(null, null, this); 
} 

@Override 
public void onPictureTaken(byte[] bytes, Camera camera) { 
    // The camera preview was automatically stopped. Start it again. 
    mCamera.startPreview(); 
    mCamera.setPreviewCallback(this); 

    Mat mat = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED); 
    Log.d(CaptureActivity.TAG, mat.toString()); 

    //an interface method to be implemented by CaptureActivity 
    if (mPictureTakenListener != null) 
     mPictureTakenListener.receivePicture(mat); 
} 

を、私は絵を受け取り、それを保存...

@Override 
public void receivePicture(Mat mat) { 
    File path = new File(Environment.getExternalStorageDirectory() + "/myCamera/"); 
    path.mkdirs(); 
    File file = new File(path, System.currentTimeMillis() + "recieved" + ".png"); 
    String filename = file.toString(); 
    Log.d(CaptureActivity.TAG, "was imwrite a success? " 
     + Imgcodecs.imwrite(filename, mat));  
} 

また、このクラスは、CameraBridgeViewBase.CvCameraViewListener2を実装...

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { 
     Log.d(TAG, "frame info " + frame.toString()); 
     return frame; 
    } 

答えて

1

あなたは正しいです。プレビューとキャプチャに同じアスペクト比を使用することはお勧めしません。あなたが見ることができるようにOpenCVのは、開口部との間のより良いフックを提供していないので、私は実際には、メソッドAllocateCache()をオーバーライドし

@Override 
protected void AllocateCache() { 
    super.AllocateCache(); 
    setPictureSize(); 
} 

protected boolean setPictureSize() { 
    try { 
     Camera.Parameters params = mCamera.getParameters(); 
     Log.d(TAG, "getSupportedPictureSizes()"); 
     List<Camera.Size> sizes = params.getSupportedPictureSizes(); 
     if (sizes == null) { 
      Log.w(TAG, "getSupportedPictureSizes() = null, cannot set a custom size"); 
      return false; 
     } 

     int maxSize = 0; 
     // choose the largest size that matches the preview AR 
     for (android.hardware.Camera.Size size : sizes) { 
      if (size.height * mFrameWidth != size.width * mFrameHeight) { 
       continue; // the picture size doesn't match 
      } 
      if (maxSize > size.width * size.height) { 
       continue; // don't need this size 
      } 
      params.setPictureSize(size.width, size.height); 
      maxSize = size.width * size.height; 
     } 
     if (maxSize == 0) { 
      Log.w(TAG, "getSupportedPictureSizes() has no matches for " + mFrameWidth + 'x' + mFrameHeight); 
      return false; 
     } 
     Log.d(TAG, "try Picture size " + params.getPictureSize().width + 'x' + params.getPictureSize().height); 
     mCamera.setParameters(params); 
    } catch (Exception e) { 
     Log.e(TAG, "setPictureSize for " + mFrameWidth + 'x' + mFrameHeight, e); 
     return false; 
    } 
    return true; 
} 

}

:だから、あなたのサブクラスでは、あなたはこのようなinitializeCamera()メソッドをオーバーライドする必要がありますカメラデバイスとプレビューを開始します。プレビューがライブ中にカメラのパラメータ(画像サイズさえも)を変更すると、一部のデバイスで失敗することがあります。

を試しても、選択したプレビューに正確に合わない画像サイズを設定することはできません。 99.9%の場合、これは問題ありませんが、奇妙なカメラには、OpenCVがレイアウト用に選択したプレビューサイズに一致する画像サイズがない場合、別のプレビューサイズを探すか、 "十分に近い"。

0

setPreviewSizesetPictureSizeを使用してくださいあなたがプレビューとtakePictureから得るものを理解してください。両方のサイズが同じではないことに注意してください(通常、takePictureで利用できるサイズはプレビューよりも大きくなる可能性があります)ので、あなたの仕事に最も適したサイズを見つけるには、getSupportedPreviewSizesgetSupportedPictureSizesを見てください。

関連する問題