Camera PreviewView在某些Android设备中被拉伸 [英] Camera PreviewView is stretched in some Android devices

查看:109
本文介绍了Camera PreviewView在某些Android设备中被拉伸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Google的API2相机,并且我的代码遇到了一些问题.我有两个不同的CameraSession,一个用于视频,另一个用于图像.为了提高效率,我将代码更改为使用唯一的Session,并提高了应用程序的效率.

I'm playing with the API2 Camera of Google and I'm having some problems with my code. I had two different CameraSessions, one for video and another one for images. To do it more efficient I change the code to use a unique Session and make the app more efficient.

完成此操作后,我的相机预览无法正常工作.当我使用4:3的长宽比时,我的预览会在高处拉伸.换句话说,当我使用16:9比例时,它看起来还不错.在这两种情况下,我的图片看起来都不错,我的意思是,预览无法正常工作,但是我拍摄的图片具有正确的宽高比.

After I did this, my camera preview is not working adequately. When I'm using a 4:3 aspect ratio my preview become stretched at height. In other way it looks fine when I'm using 16:9 ratio. In both cases my pictures looks fine, I mean, preview doesn't work correctly but the pictures that I took, have the correct aspect ratio.

我已经检查了具有相同问题的其他帖子: 在很少的Android设备上扩展了相机预览

I already check different post with the same problem: Camera Preview Stretched on Few Android Devices

相机全屏显示/预览不保持宽高比-图像倾斜,拉伸以适合屏幕尺寸

但是不同的答案并没有帮助我.我知道问题出在我的onMeasure()setTransformMatrix()OnLayoutChangeListener()方法内部,但是我不知道我在做什么错.

But the different answers didn't help me. I know that the problem is inside my onMeasure(), setTransformMatrix() or OnLayoutChangeListener() methods, but I don't know what I'm doing wrong.

忽略关于旋转的代码,现在它是动态的.它总是在其他情况下进入.

Ignore the code about Rotation, right now it's dynamic. It always enter at else condition.

这是我的代码:

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

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

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 + "]");

}

推荐答案

已解决!

我有我的纹理的BufferSize的默认值,当我初始化一个新的Session或更改after比率后,这些值才重新启动.但是纹理的Width和Height值未使用该比率进行更新,因此它一次又一次地被拉伸.

I had a default values for the BufferSize of my texture, which just are restarted when I inicializated a new Session or after change the after ratio. But the Width and Height values for the texture were not updated with the ratio, so it becomes streched again and again.

我解决了使用PreviewSizes更改我的defaultbufferSize的问题,我会始终通过更改比率来进行更新.

I solved it changing my defaultbufferSize with the PreviewSizes which I update always that i change the ratio.

   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);
.......

这篇关于Camera PreviewView在某些Android设备中被拉伸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆