2017-12-05 38 views
0

이것은 Google 비전 API에 관한 것입니다. CameraPreview는 전체 화면에서 잘 작동합니다. 그러나 상자에서 카메라를 미리 볼 때 이미지가 왜곡됩니다.setPreviewSize 및 PictureSize와 같은 CameraSource 크기를 변경하는 방법

이것은 내가 사용한 코드입니다. 내 문제는 미리보기가 상자를 채우지 만 미리보기가 늘어나고 cameraPreview의 크기를 조정할 수 없다는 것입니다. 변수 CameraPreview는 SurfaceView 유형입니다. CameraSource를 사용하여 미리보기를 시작합니다. CameraPreview (SurfaceView)의 크기를 변경하고 미리보기 자르기를 상자에 맞게 만들 수있는 방법이 있습니까? 같은 문제가 '전체 화면' 카메라 미리보기 존재

cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() { 
      protected List<Camera.Size> mPreviewSizeList; 
      protected List<Camera.Size> mPictureSizeList; 
      protected Camera.Size mPreviewSize; 
      protected Camera.Size mPictureSize; 
      protected boolean mSurfaceChanged = false; 
      private int mSurfaceChangedCallDepth = 0; 
      private int mCenterPosX = -1; 
      private int mCenterPosY = 0; 
      @Override 
      public void surfaceCreated(SurfaceHolder surfaceHolder) { 
       if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
        ActivityCompat.requestPermissions(ClientIdScannerActivity.this, 
          new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionId); 
        Toast.makeText(ClientIdScannerActivity.this, "The App requires this permission", Toast.LENGTH_SHORT).show(); 
        return; 
       } 
       try { 
        cameraSource.start(cameraPreview.getHolder()); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
      @Override 
      public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { 
       mSurfaceChangedCallDepth++; 

      /* cameraSource.stop(); 

       Camera.Parameters cameraParams = mCamera.getParameters(); 

       if (!mSurfaceChanged) { 
        Camera.Size previewSize = determinePreviewSize(cameraWidth, cameraHight); 
        Camera.Size pictureSize = determinePictureSize(previewSize); 
        mPreviewSize = previewSize; 
        mPictureSize = pictureSize; 
        mSurfaceChanged = adjustSurfaceLayoutSize(previewSize,i1, i2); 

        if (mSurfaceChanged && (mSurfaceChangedCallDepth <= 1)) { 
         return; 
        } 
       } 

       cameraParams.setRotation(270); 
       if (UtilFunctions.isTablet()) { 
       } else { 
        mCamera.setDisplayOrientation(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? 270 : 90); 
       }*/ 

//   cameraParams.setRotation(270); 
//   mCamera.setDisplayOrientation(UtilFunctions.isTablet() ? 90 : 270); 

       /* cameraParams.set("orientation", "portrait"); 
       // cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
       cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
       cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height); 
       if (cameraParams.getSupportedFocusModes().contains(
         Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { 
        cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
       }*/ 

       mSurfaceChanged = false; 

       try { 
        if (ActivityCompat.checkSelfPermission(ClientIdScannerActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 
         // TODO: Consider calling 
         // ActivityCompat#requestPermissions 
         // here to request the missing permissions, and then overriding 
         // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
         //           int[] grantResults) 
         // to handle the case where the user grants the permission. See the documentation 
         // for ActivityCompat#requestPermissions for more details. 
         Toast.makeText(ClientIdScannerActivity.this, "App requires Camera permission to scan ID", Toast.LENGTH_SHORT).show(); 
         return; 
        } 
        cameraSource.start(cameraPreview.getHolder()); 
       } catch (Exception e) { 
        // Remove failed size 

        // Reconfigure 
        if (mPreviewSizeList.size() > 0) { // prevent infinite loop 
         surfaceChanged(null, 0, i1, i2); 
        } else { 
//    Utils.showToast(CameraNewActivity.this, "Can't start preview", Toast.LENGTH_LONG); 
        } 
       } 

       mSurfaceChangedCallDepth--; 
      } 

      protected Camera.Size determinePreviewSize(int reqWidth, int reqHeight) { 

       int reqPreviewWidth = 640;//reqHeight; // requested width in terms of camera hardware 
       int reqPreviewHeight = 480;// reqWidth; // requested height in terms of camera hardware 
       Camera.Size retSize = null; 
       for (Camera.Size size : mPreviewSizeList) { 
        if (size.width == reqPreviewWidth && size.height == reqPreviewHeight) { 
         retSize = size; 
        } 
       } 
       // retSize = mPreviewSizeList.get(mPreviewSizeList.size()-1); 
       return retSize; 
      } 

      protected Camera.Size determinePictureSize(Camera.Size previewSize) { 
       Camera.Size retSize = null; 
       for (Camera.Size size : mPictureSizeList) { 
        if (size.equals(previewSize)) { 
         return size; 
        } 
       } 

       // if the preview size is not supported as a picture size 
       float reqRatio = ((float) previewSize.width)/previewSize.height; 
       float curRatio, deltaRatio; 
       float deltaRatioMin = Float.MAX_VALUE; 
       for (Camera.Size size : mPictureSizeList) { 
        curRatio = ((float) size.width)/size.height; 
        deltaRatio = Math.abs(reqRatio - curRatio); 
        if (deltaRatio < deltaRatioMin) { 
         deltaRatioMin = deltaRatio; 
         retSize = size; 
        } 
       } 

       return retSize; 
      } 

      protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize, 
                 int availableWidth, int availableHeight) { 

       float tmpLayoutHeight = previewSize.width; 
       float tmpLayoutWidth = previewSize.height; 

       float factH, factW, fact; 
       factH = availableHeight/tmpLayoutHeight; 
       factW = availableWidth/tmpLayoutWidth; 

//  if (factH < factW) { 
//   fact = factH; 
//  } else { 
       fact = factW; 
       // } 

       FrameLayout.LayoutParams layoutParams =(FrameLayout.LayoutParams) cameraPreview.getLayoutParams(); 
       int layoutHeight = (int) (tmpLayoutHeight * fact); 
       int layoutWidth = (int) (tmpLayoutWidth * fact); 

       boolean layoutChanged; 
       if ((layoutWidth != cameraPreview.getWidth()) || (layoutHeight != cameraPreview.getHeight())) { 
        layoutParams.height = layoutHeight; 
        layoutParams.width = layoutWidth; 
        if (mCenterPosX >= 0) { 
         layoutParams.topMargin = mCenterPosY - (layoutHeight/2); 
         layoutParams.leftMargin = mCenterPosX - (layoutWidth/2); 
        } 
        cameraPreview.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation. 
        layoutChanged = true; 
       } else { 
        layoutChanged = false; 
       } 

       return layoutChanged; 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
       cameraSource.stop(); 
      } 
     }); 
+0

이 코드는 실행되지만 효과는 없습니다. 이전에는 Camera 변수를 사용했지만 더 이상 필요하지 않으므로 주석을 달았습니다. 내 이해가. –

답변

0

참고. 선택한 미리보기 크기의 종횡비가 화면의 종횡비에 충분히 근접 할 것이라는 보장은 없습니다. 자세한 내용은 여기를 참조하십시오 : Camera Preview Stretched on Few Android Devices.

자연스럽게 너비와 높이를 선택하여보기에 적합해야하지만 충분하지 않습니다. 투명한 뷰 뒤에 미리보기 표면의 '매달린'부분을 숨겨야합니다. 예를 들어 make a circular preview 수있는 방법을 참조하십시오.

또 다른 중요한 점은 항상 미리보기와 그림 크기를 동기화 상태로 유지하는 것입니다. 이것은 동일해야 함을 의미하지는 않지만 가로 세로 비율은 같아야합니다. 일부 장치는 사진을 캡처하기 위해 종횡비가 변경되면 이상한 효과를냅니다.

+0

제안 해 주셔서 감사합니다. –