相机previewView在一些Android设备streched [英] Camera PreviewView is streched in some android devices

查看:944
本文介绍了相机previewView在一些Android设备streched的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在IM播放与谷歌和IM有一些问题,我的code中的API2相机。我有两个不同CameraSessions,一个用于视频,另一个用于图像。要做到这一点更有效的I改变code使用唯一的会话,使应用程序更高效。

做到这一点后,我的相机preVIEW没有充分的工作。当即时通讯使用的是4:3纵横比我的preVIEW成为高度streched。 9比例:在其他的方式,它使用16时,林看起来不错。
在这两种情况下,我的图片看起来不错,我的意思是,正确的preVIEW不工作,但我抽放的照片,有正确的纵横比。

我已经检查不同岗位同样的问题:
<一href=\"http://stackoverflow.com/questions/30049293/camera-$p$pview-stretched-on-few-android-devices/30153071#30153071\">Camera preVIEW舒展了几个Android设备

<一个href=\"http://stackoverflow.com/questions/16727836/camera-display-$p$pview-in-full-screen-does-not-maintain-aspect-ratio-image-i#comment32834289_16733405\">Camera在全屏幕显示/ preVIEW不保持高宽比 - 图像歪斜,以适应屏幕上的捉襟见肘

但不同的答案没有帮助我。我知道这个问题是我里面的 onMeasure(),setTransformMatrix()或OnLayoutChangeListener()方法,但我不知道我在做什么错。

忽略code左右轮换,现在它的动态。它总是在别的条件下进入。

下面是我的code:

 私人OnLayoutChangeListener mLayoutListener =新OnLayoutChangeListener(){
    @覆盖
    公共无效onLayoutChange(视图V,诠释离开,诠释顶部,向右诠释,
                               INT底部,诠释oldLeft,诠释oldTop,诠释oldRight,诠释oldBottom){        Log.d(TAG,[onLayoutChange]+ mCameraUI.getTextureView()getMeasuredWidth()+×+ mCameraUI.getTextureView()getMeasuredHeight());        INT宽度=右 - 左;
        INT高=底 - 顶;
        如果(M previewWidth!= ||宽度米previewHeight!=身高
                || (mOrientationResize!= M prevOrientationResize)
                || mAspectRatioResize || mOrientationChanged){            Log.i(TAG[onLayoutChange]布局改变);
            米previewWidth =宽度;
            米previewHeight =高度;
            Log.i(TAG[onLayoutChange] preVIEW大小:+ M previewWidth +X+ M previewHeight);
            setTransformMatrix(宽度,高度);
            mController.onScreenSizeChanged((INT)mSurfaceTextureUncroppedWidth,
                    (INT)mSurfaceTextureUncroppedHeight);
            mAspectRatioResize = FALSE;
            mOrientationChanged = TRUE;
        }
    }
};

的setTransform

 私人无效setTransformMatrix(INT宽度,高度INT){
    Log.i(TAG,屏幕显示:+ M previewWidth +X+ M previewHeight);    mMatrix =新的Matrix();
    //mCameraUI.getTextureView().getTransform(mMatrix);
    漂浮的scaleX = 1F,的scaleY = 1F;
    浮scaledTextureWidth,scaledTextureHeight;     mAspectRatio =(浮点)高度/(浮点)宽度;
    如果(mAspectRatio ==(4F / 3F)){            scaledTextureWidth = Math.max(宽度,
                    (中间体)(高度/ mAspectRatio));
            scaledTextureHeight = Math.max(高度,
                    (INT)(宽* mAspectRatio));
        Log.i(TAG[PhotoUIManager]:宽高比4:3 =+ scaledTextureWidth +X+ scaledTextureHeight);
    }
    其他{
        scaledTextureWidth = Math.max(宽度,
                (中间体)(高度/ mAspectRatio));
        scaledTextureHeight = Math.max(高度,
                (INT)(宽* mAspectRatio));
        Log.i(TAG[PhotoUIManager]:宽高比16:9 =+ scaledTextureWidth +X+ scaledTextureHeight);
    }
    如果(mSurfaceTextureUncroppedWidth!= scaledTextureWidth || mSurfaceTextureUncroppedHeight!= scaledTextureHeight){
        Log.e(TAG,MI SurfaceWidth =+ mSurfaceTextureUncroppedWidth +和MI scaledWidth =+ scaledTextureWidth);
        Log.e(TAG,MI SurfaceHeigh =+ mSurfaceTextureUncroppedHeight +和MI scaledHeight =+ scaledTextureHeight);
        mSurfaceTextureUncroppedWidth = scaledTextureWidth;
        mSurfaceTextureUncroppedHeight = scaledTextureHeight;
        Log.e(TAG,面+ mSurfaceTextureUncroppedWidth +X+ mSurfaceTextureUncroppedHeight);
        如果(mSurfaceTextureSizeListener!= NULL){
            mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
                    (INT)mSurfaceTextureUncroppedWidth,(INT)mSurfaceTextureUncroppedHeight);
        }
    }
    将scaleX = scaledTextureWidth /宽度;
    的scaleY = scaledTextureHeight /高度;
    mMatrix.setScale(将scaleX,的scaleY,scaledTextureWidth / 2,scaledTextureHeight / 2);
    Log.e(TAG,规模:X =+ +的scaleXY =+ +的scaleYWIDTH =+ scaledTextureWidth +HEIGHT =+ scaledTextureHeight);    //初始化的位置(这似乎是必要过于当该比值16/9
    mCameraUI.getTextureView()setX的(0)。
    。mCameraUI.getTextureView()SETY(0);    //翻译了preVIEW用旋转宽比为4/3
    如果(mAspectRatio == 4F / 3F){
        Log.e(TAG,宽高比标准);
        浮verticalTranslateOffset =(mCameraUI.getTextureView()getMeasuredHeight() - scaledTextureHeight。)/ 2;
        浮horizo​​ntalTranslateOffset =(mCameraUI.getTextureView()getMeasuredWidth() - scaledTextureWidth。)/ 2;
        INT旋转= CameraUtil.getDisplayRotation(mActivity);
        开关(旋转){
            情况下0:
                //电话画像;翻译preVIEW起来
                。mCameraUI.getTextureView()塞蒂(-verticalTranslateOffset);
                mFaceView.setStandard previewTranslationOffset(-verticalTranslateOffset);
                mFocusView.setStandard previewTranslationOffset(-verticalTranslateOffset);
                打破;
            案例90:
                //电话景观:翻译preVIEW左
                。mCameraUI.getTextureView()setX的(-horizo​​ntalTranslateOffset);
                mFaceView.setStandard previewTranslationOffset(-horizo​​ntalTranslateOffset);
                mFocusView.setStandard previewTranslationOffset(-horizo​​ntalTranslateOffset);
                打破;
            案例180:
                //电话倒挂:翻译preVIEW底部
                。mCameraUI.getTextureView()塞蒂(verticalTranslateOffset);
                mFaceView.setStandard previewTranslationOffset(verticalTranslateOffset);
                mFocusView.setStandard previewTranslationOffset(verticalTranslateOffset);
                打破;
            案例270:
                //反转景观:翻译preVIEW权
                。mCameraUI.getTextureView()setX的(horizo​​ntalTranslateOffset);
                mFaceView.setStandard previewTranslationOffset(horizo​​ntalTranslateOffset);
                mFocusView.setStandard previewTranslationOffset(horizo​​ntalTranslateOffset);
                打破;
        }    }其他{
        Log.e(TAG,宽高比全);
        mFaceView.setStandard previewTranslationOffset(0);
        mFocusView.setStandard previewTranslationOffset(0);
    }    mRenderOverlay.updateLayout();
    mCameraUI.getTextureView()的setTransform(mMatrix)。    RectF previewRect =新RectF(0,0,宽度,高度);    mController.on previewRectChanged(CameraUtil.rectFToRect(previewRect));}

onMeasure

 保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
    super.onMeasure(widthMeasureSpec,heightMeasureSpec);
    INT宽度= MeasureSpec.getSize(widthMeasureSpec);
    INT高度= MeasureSpec.getSize(heightMeasureSpec);    Log.d(TAGonMeasure preVIOUS宽x高。[+ widthMeasureSpec +=+宽+X+ heightMeasureSpec +=+高度+]);    INT旋转=((活动)的getContext())getWindowManager()getDefaultDisplay()getRotation()。;
    布尔isInHorizo​​ntal = Surface.ROTATION_90 == ||旋转Surface.ROTATION_270 ==转动;    INT newWidth;
    INT newHeight;    如果(isInHorizo​​ntal){        newHeight = getMeasuredHeight();
        newWidth =(INT)(newHeight * mAspectRatio);
    }其他{        newWidth = getMeasuredWidth();
        newHeight =(INT)(newWidth * mAspectRatio);
    }    setMeasuredDimension(newWidth,newHeight);
    Log.d(TAG。onMeasure宽度x高度[+ newWidth +×+ newHeight +]);}


解决方案

解决了!

我对我的纹理缓冲区大小,当我inicializated一个新的会话或变更后的比例后刚刚重新启动缺省值。但没有更新,比对纹理的宽度和高度值,因此它成为一次又一次streched。

我解决它改变了我的defaultbufferSize与previewSizes我始终认为我改变比例进行更新。

 公共无效createCamera previewSession(尺寸previewsize,表面recordingSurface){
    尝试{
        如果(mCaptureSession!= NULL){
            mCaptureSession.sto prepeating();
            mCaptureSession.close();
            mCaptureSession = NULL;
        }        质地表面纹理= mTextureView.getSurfaceTexture();
        断言质感!= NULL;        清单&lt;表面&GT;表面=新的ArrayList&lt;表面&GT;();        //我们配置默认缓冲区的大小是我们想要的相机preVIEW的大小。
        texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
        ;
        //这是我们需要开始preVIEW输出表面。
        面面=新的表面(质感);
.......

Right now im playing with the API2 Camera of google and im 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.

After do this, my camera preview is not working adequately. When Im using a 4:3 aspect ratio my preview become streched at height. In other way it looks fine when Im using 16:9 ratio. In both cases my pictures looks fine, I mean, preview doesnt work correctly but the pictures that I taked, have the correct aspect ratio.

I already check different post with the same problem: 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

But the different answers didnt help me. I know that the problem is inside my onMeasure() , setTransformMatrix() or OnLayoutChangeListener() methods, but I dont know what iḿ doing wrong.

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

Here is my code:

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

}

解决方案

Solved!

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.

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

这篇关于相机previewView在一些Android设备streched的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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