2017-01-11 13 views
1

通常、PreviewCallbackを搭載したアンドロイドカメラのapiは、撮影後にカメラをフリーズさせ、撮影した画像の承認画面として使用できます。私の問題は、これはサムスンS6とS6のエッジのような携帯電話での動作ではないということです。写真を撮った後、2台の電話機はライブプレビューを続けます。特定のデバイスで撮影された画像のAndroidカメラのプレビュー

撮影した写真はまだ良好で、後で使用することもできますが、プレビューは表示されません。また、自分のアプリの設定方法は、ユーザーが確認したxの写真。代わりに、彼らはチェックのためのこのオーバーレイと "x"と背景のライブプレビューを持っています。これはsamsung s6/s6エッジでのみ発生します。

特定のデバイスでこのような問題が発生する可能性がありますか?プレビューと絵はどこにでも、いくつかのログを取るために使用さ

コード:

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    // SurfaceHolder 
    private SurfaceHolder mHolder; 

    // Our Camera. 
    private Camera mCamera; 

    // Parent Context. 
    private Context mContext; 

    // Camera Sizing (For rotation, orientation changes) 
    private Camera.Size mPreviewSize; 

    // List of supported preview sizes 
    private List<Camera.Size> mSupportedPreviewSizes; 
    private List<Camera.Size> mSupportPictureSizes; 

    // Flash modes supported by this camera 
    private List<String> mSupportedFlashModes; 

    // View holding this camera. 
    private View mCameraView; 

    public CameraPreview(Context context, Camera camera, View cameraView) { 
     super(context); 

     Log.d(TAG, "CameraPreview: "); 

     // Capture the context 
     mCameraView = cameraView; 
     mContext = context; 
     setCamera(camera); 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
//   mHolder.setKeepScreenOn(true); 
     // deprecated setting, but required on Android versions prior to 3.0 
//   mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    /** 
    * Begin the preview of the camera input. 
    */ 
    public void startCameraPreview() 
    { 
     Log.d(TAG, "startCameraPreview: "); 
     try{ 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Extract supported preview and flash modes from the camera. 
    * @param camera 
    */ 
    private void setCamera(Camera camera) 
    { 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     mCamera = camera; 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     mSupportPictureSizes = mCamera.getParameters().getSupportedPictureSizes(); 

     for(Camera.Size size : mSupportedPreviewSizes){ 
      Log.d(TAG, "supportedPreviewSizes width: " + size.width + " x " + size.height); 
     } 
     for(Camera.Size size : mSupportPictureSizes){ 
      Log.d(TAG, "mSupportPictureSizes width: " + size.width + " x " + size.height); 
     } 
     mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes(); 
     Camera.Parameters parameters = mCamera.getParameters(); 

     parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 

     // Set the camera to Auto Flash mode. 
     if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)){ 
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 

     } 

     mCamera.setParameters(parameters); 
     requestLayout(); 
    } 

    /** 
    * The Surface has been created, now tell the camera where to draw the preview. 
    * @param holder 
    */ 
    public void surfaceCreated(SurfaceHolder holder) { 
     Log.d(TAG, "surfaceCreated: "); 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Dispose of the camera preview. 
    * @param holder 
    */ 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.d(TAG, "surfaceDestroyed: "); 
     if (mCamera != null){ 
      mCamera.stopPreview(); 
     } 
    } 

    /** 
    * React to surface changed events 
    * @param holder 
    * @param format 
    * @param w 
    * @param h 
    */ 
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // If your preview can change or rotate, take care of those events here. 
     // Make sure to stop the preview before resizing or reformatting it. 

     if (mHolder.getSurface() == null){ 
      // preview surface does not exist 
      Log.d(TAG, "surfaceChanged: preview surface does not exist"); 
      return; 
     } 
     Log.d(TAG, "surfaceChanged: start & stop preview"); 
     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e){ 
      // ignore: tried to stop a non-existent preview 
     } 

     // set preview size and make any resize, rotate or 
     // reformatting changes here 

     // start preview with new settings 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

     } catch (Exception e){ 
      Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
     } 

    } 

    @Override 
    public SurfaceHolder getHolder() { 
     return super.getHolder(); 
    } 

    /** 
    * Calculate the measurements of the layout 
    * @param widthMeasureSpec 
    * @param heightMeasureSpec 
    */ 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 

     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(width, height); 

     if (mSupportedPreviewSizes != null){ 
      Log.d(TAG, "onMeasure: w x h: " + width + " x " + height); 
      mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
     } 
    } 

    /** 
    * Update the layout based on rotation and orientation changes. 
    * @param changed 
    * @param left 
    * @param top 
    * @param right 
    * @param bottom 
    */ 
    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
    { 
     Log.d(TAG, "onLayout: "); 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     if (changed) { 
      final int width = right - left; 
      final int height = bottom - top; 

      int previewWidth = width; 
      int previewHeight = height; 

      if (mPreviewSize != null){ 
       Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 

       switch (display.getRotation()) 
       { 
        case Surface.ROTATION_0: 
         previewWidth = mPreviewSize.height; 
         previewHeight = mPreviewSize.width; 
         mCamera.setDisplayOrientation(90); 
         Log.d(TAG, "onLayout: rotation0"); 
         break; 
        case Surface.ROTATION_90: 
         previewWidth = mPreviewSize.width; 
         previewHeight = mPreviewSize.height; 
         Log.d(TAG, "onLayout: rotation90"); 
         break; 
        case Surface.ROTATION_180: 
         previewWidth = mPreviewSize.height; 
         previewHeight = mPreviewSize.width; 
         Log.d(TAG, "onLayout: rotation180"); 
         break; 
        case Surface.ROTATION_270: 
         previewWidth = mPreviewSize.width; 
         previewHeight = mPreviewSize.height; 
         mCamera.setDisplayOrientation(180); 
         Log.d(TAG, "onLayout: rotation270"); 
         break; 
       } 
      } 

      final int scaledChildHeight = previewHeight * width/previewWidth; 
      mCameraView.layout(0, height - scaledChildHeight, width, height); 
     } 
    } 

    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 
     Log.d(TAG, "getOptimalPreviewSize: "); 
     final double ASPECT_TOLERANCE = 0.05; 
     double targetRatio = (double) w/h; 
     if (sizes == null) return null; 

     Camera.Size optimalSize = null; 
     double minDiff = Double.MAX_VALUE; 

     int targetHeight = h; 

     // Try to find an size match aspect ratio and size 
     for (Camera.Size size : sizes) { 
      double ratio = (double) size.width/size.height; 
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE){ 
       continue; 
      } 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       Log.d(TAG, "getOptimalPreviewSize: found a match"); 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     // Cannot find the one match the aspect ratio, ignore the requirement 
     if (optimalSize == null) { 
      Log.d(TAG, "getOptimalPreviewSize: couldn't find match"); 
      minDiff = Double.MAX_VALUE; 
      for (Camera.Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     Log.d(TAG, "getOptimalPreviewSize: " + optimalSize.width + " x HEIGHT: " + optimalSize.height); 
     return optimalSize; 

    } 

} 


/** 
* Picture Callback for handling a picture capture and saving it out to a file. 
*/ 
private Camera.PictureCallback mPicture = new Camera.PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     Camera.Parameters parameters = camera.getParameters(); 
     Camera.Size mPictureTakenSize = parameters.getPictureSize(); 
     System.out.println("picture taken size: " + mPictureTakenSize.width + " x " + mPictureTakenSize.height); 
     if(data!=null){ 
      Log.d(TAG, "onPictureTaken: data not null, setting data to currentData"); 
//    currentData = data; 
      setPictureTakenData(data); 
      cameraViewModel.setPreview(true); 
     } 
     else{ 
      onProgress = false; 
      Log.d(TAG, "onPictureTaken: data is null"); 
     } 

    } 
}; 

答えて

0

私はちょうど同じ問題に遭遇しました。 PictureCallbackのonPictureTakenメソッドでcamera.stopPreview()を手動で呼び出すことで修正できるようです。写真を撮影した後

0

カメラは手動で)あなたがmCamera.stopPreviewを(呼び出す必要があるので、自動的にプレビューを停止することはありません。

if (mCamera != null) { 
    try { 
     mCamera.stopPreview(); 
     pauseFlash(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

// if current camera flash mode is TORCH, you need pause it. 
private void pauseFlash() { 
    if (currentFlashMode.equals(Camera.Parameters.FLASH_MODE_TORCH)) { 
     params = mCamera.getParameters(); 
     params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
     mCamera.setParameters(params); 
    } 
} 

そして、後に何かをしてカメラのプレビューに戻って移動します。

@Override 
public void startCameraPreview() { 
    if (mCamera != null) { 
     try { 
      mCamera.startPreview(); 
      resumeFlash(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      // TAKE CARE IF YOUR CAMERA HAS BEEN RELEASED 
     } 
    } 
} 

void resumeFlash() { 
    flashChange(currentFlashMode); 
} 

私はいくつかのパフォーマンス上のヒントを持っています:ユーザーがあなたのアプリを初めて使うときに、最高の画像サイズとプレビューサイズを見つけて、それらをSharedPreferencesに保存してください。

このヘルプが必要です。

関連する問題