2016-02-05 5 views
2

Прямо сейчас я играю с камерой API2 Google google и im, имеющей некоторые проблемы с моим кодом. У меня было две разные камеры, одна для видео и другая для изображений. Чтобы сделать это более эффективным, я меняю код на использование уникального сеанса и повышаю эффективность приложения.Camera PreviewView растягивается в некоторых устройствах Android.

После этого предварительный просмотр камеры не работает должным образом. Когда Im использует соотношение сторон 4: 3, мой просмотр становится растянутым на высоте. Другим способом это выглядит отлично, когда Im использует соотношение 16: 9. В обоих случаях мои фотографии выглядят отлично, я имею в виду, что предварительный просмотр не работает правильно, но изображения, которые я использовал, имеют правильное соотношение сторон.

я уже проверить другую должность с той же проблемой: Camera Preview Stretched on Few Android Devices

Camera display/preview in full screen does not maintain aspect ratio - image is skewed, stretched in order to fit on the screen

Но различные ответы не помогли мне. Я знаю, что проблема в моих методах onMeasure() , setTransformMatrix() or OnLayoutChangeListener(), но я не знаю, что я делаю неправильно.

Пропустить код про Rotation, сейчас его динамика. Он всегда входит в другое состояние.

Вот мой код:

private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() { 
    @Override 
    public void onLayoutChange(View v, int left, int top, int right, 
           int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 

     Log.d(TAG, "[onLayoutChange] " + mCameraUI.getTextureView().getMeasuredWidth() + "x" + mCameraUI.getTextureView().getMeasuredHeight()); 

     int width = right - left; 
     int height = bottom - top; 
     if (mPreviewWidth != width || mPreviewHeight != height 
       || (mOrientationResize != mPrevOrientationResize) 
       || mAspectRatioResize || mOrientationChanged) { 

      Log.i(TAG, "[onLayoutChange] Layout changed"); 
      mPreviewWidth = width; 
      mPreviewHeight = height; 
      Log.i(TAG, "[onLayoutChange] Preview size: "+ mPreviewWidth + "x" + mPreviewHeight); 
      setTransformMatrix(width, height); 
      mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth, 
        (int) mSurfaceTextureUncroppedHeight); 
      mAspectRatioResize = false; 
      mOrientationChanged = true; 
     } 
    } 
}; 

SetTransform

private void setTransformMatrix(int width, int height) { 


    Log.i(TAG, "Screen: " + mPreviewWidth + "x" + mPreviewHeight); 

    mMatrix = new Matrix(); 
    //mCameraUI.getTextureView().getTransform(mMatrix); 
    float scaleX = 1f, scaleY = 1f; 
    float scaledTextureWidth, scaledTextureHeight; 

    mAspectRatio= (float)height/(float)width; 
    if (mAspectRatio==(4f/3f)){ 

      scaledTextureWidth = Math.max(width, 
        (int) (height/mAspectRatio)); 
      scaledTextureHeight = Math.max(height, 
        (int) (width * mAspectRatio)); 
     Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 4:3=" + scaledTextureWidth + "x" + scaledTextureHeight); 
    } 
    else{ 
     scaledTextureWidth = Math.max(width, 
       (int) (height/mAspectRatio)); 
     scaledTextureHeight = Math.max(height, 
       (int) (width * mAspectRatio)); 
     Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 16:9=" + scaledTextureWidth + "x" + scaledTextureHeight); 
    }  


    if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || mSurfaceTextureUncroppedHeight != scaledTextureHeight) { 
     Log.e(TAG,"mi SurfaceWidth = " + mSurfaceTextureUncroppedWidth + "and mi scaledWidth=" + scaledTextureWidth); 
     Log.e(TAG,"mi SurfaceHeigh = " + mSurfaceTextureUncroppedHeight + "and mi scaledHeight=" + scaledTextureHeight); 
     mSurfaceTextureUncroppedWidth = scaledTextureWidth; 
     mSurfaceTextureUncroppedHeight = scaledTextureHeight; 
     Log.e(TAG,"Surfaces: " + mSurfaceTextureUncroppedWidth + "x" + mSurfaceTextureUncroppedHeight); 
     if (mSurfaceTextureSizeListener != null) { 
      mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
        (int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight); 
     } 
    } 
    scaleX = scaledTextureWidth/width; 
    scaleY = scaledTextureHeight/height; 
    mMatrix.setScale(scaleX, scaleY, scaledTextureWidth/2, scaledTextureHeight/2); 
    Log.e(TAG, "scale: X= " + scaleX + " Y=" + scaleY + "Width= " + scaledTextureWidth + "Height= " + scaledTextureHeight); 

    // init the position (this seems to be necessary too when the ratio is 16/9 
    mCameraUI.getTextureView().setX(0); 
    mCameraUI.getTextureView().setY(0); 

    // Translate the preview with the rotation is aspect ration is 4/3 
    if (mAspectRatio == 4f/3f) { 
     Log.e(TAG, "aspect ratio standard"); 
     float verticalTranslateOffset = (mCameraUI.getTextureView().getMeasuredHeight() - scaledTextureHeight)/2; 
     float horizontalTranslateOffset = (mCameraUI.getTextureView().getMeasuredWidth() - scaledTextureWidth)/2; 
     int rotation = CameraUtil.getDisplayRotation(mActivity); 
     switch (rotation) { 
      case 0: 
       // phone portrait; translate the preview up 
       mCameraUI.getTextureView().setY(-verticalTranslateOffset); 
       mFaceView.setStandardPreviewTranslationOffset(-verticalTranslateOffset); 
       mFocusView.setStandardPreviewTranslationOffset(-verticalTranslateOffset); 
       break; 
      case 90: 
       // phone landscape: translate the preview left 
       mCameraUI.getTextureView().setX(-horizontalTranslateOffset); 
       mFaceView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset); 
       mFocusView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset); 
       break; 
      case 180: 
       // phone upside down: translate the preview bottom 
       mCameraUI.getTextureView().setY(verticalTranslateOffset); 
       mFaceView.setStandardPreviewTranslationOffset(verticalTranslateOffset); 
       mFocusView.setStandardPreviewTranslationOffset(verticalTranslateOffset); 
       break; 
      case 270: 
       // reverse landscape: translate the preview right 
       mCameraUI.getTextureView().setX(horizontalTranslateOffset); 
       mFaceView.setStandardPreviewTranslationOffset(horizontalTranslateOffset); 
       mFocusView.setStandardPreviewTranslationOffset(horizontalTranslateOffset); 
       break; 
     } 

    } else { 
     Log.e(TAG, "aspect ratio full"); 
     mFaceView.setStandardPreviewTranslationOffset(0); 
     mFocusView.setStandardPreviewTranslationOffset(0); 
    } 

    mRenderOverlay.updateLayout(); 
    mCameraUI.getTextureView().setTransform(mMatrix); 

    RectF previewRect = new RectF(0, 0, width, height); 

    mController.onPreviewRectChanged(CameraUtil.rectFToRect(previewRect)); 

} 

onMeasure

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 

    Log.d(TAG, "onMeasure PREVIOUS. Width x Height [" + widthMeasureSpec + " = " + width + "x" + heightMeasureSpec + " = " + height + "]"); 

    int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation(); 
    boolean isInHorizontal = Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation; 

    int newWidth; 
    int newHeight; 

    if (isInHorizontal) { 

     newHeight = getMeasuredHeight(); 
     newWidth = (int) (newHeight * mAspectRatio); 
    } else { 

     newWidth = getMeasuredWidth(); 
     newHeight = (int) (newWidth * mAspectRatio); 
    } 

    setMeasuredDimension(newWidth, newHeight); 
    Log.d(TAG, "onMeasure. Width x Height [" + newWidth + "x" + newHeight + "]"); 

} 

ответ

1

решенный!

У меня были значения по умолчанию для BufferSize моей текстуры, которые просто перезапускаются, когда я инициализировал новый сеанс или после изменения коэффициента after. Но значения ширины и высоты для текстуры не были обновлены с отношением, поэтому он становится растянутым снова и снова.

Я решил это изменить свой defaultbufferSize с PreviewSizes, который я постоянно обновляю, чтобы изменить коэффициент.

public void createCameraPreviewSession(Size previewsize, Surface recordingSurface) { 
    try { 
     if (mCaptureSession != null) { 
      mCaptureSession.stopRepeating(); 
      mCaptureSession.close(); 
      mCaptureSession = null; 
     } 

     SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
     assert texture != null; 

     List<Surface> surfaces = new ArrayList<Surface>(); 

     // We configure the size of default buffer to be the size of camera preview we want. 
     texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight()); 
     ; 
     // This is the output Surface we need to start preview. 
     Surface surface = new Surface(texture); 
....... 
Смежные вопросы