使用TextureView setTransform(Matrix)方法,解决Camera显示变形问题

jluzc@aliyun.com

使用SurfaceView和TextureView进行Camera开发的时候不可避免的会遇到一个问题:Camera 显示图像变形,图像被拉伸或者手机旋转一定角度(小于90度)图像变形。

总结有三种方法可以解决这个问题:

1. 自定义layout,将SurfaceView 和 TextureView addView到此layout,然后通过onLayou, onMeasue,控制SurfaceView及TextureView大小。

2. 使用SurfaceView和TextureView自带的setLayoutParams(params) 属性设置控件大小。

3. 通过TextureView 的setTransform(matrix)方法,控制Camera显示范围 (SurfaceView没有 setTransform 属性)

下面是TextureView使用 setTransform(matrix)方法控制Camera显示范围的代码


public class MainActivity extends Activity implements SurfaceTextureListener,

OnLayoutChangeListener {
private TextureView textureView;
Matrix matrix;
Camera camera;
int mWidth = 0;
int mHeight = 0;
int mDisplayWidth = 0;
int mDisplayHeight = 0;
int mPreviewWidth = 640;
int mPreviewHeight = 480;
int orientation = 0;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = (TextureView) findViewById(R.id.texture);
textureView.addOnLayoutChangeListener(this);
textureView.setSurfaceTextureListener(this);
camera = Camera.open();
}


@Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
// TODO Auto-generated method stub
mWidth = right - left;
mHeight = bottom - top;
}


@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height) {
// TODO Auto-generated method stub
RectF previewRect = new RectF(0, 0, mWidth, mHeight);
double aspect = (double) mPreviewWidth / mPreviewHeight;

        if (getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_PORTRAIT) {
         aspect = 1 / aspect;
        }

if(mWidth < (mHeight * aspect)) {
mDisplayWidth = mWidth;
mDisplayHeight = (int) (mHeight * aspect + .5);
} else {   
mDisplayWidth = (int) (mWidth / aspect + .5);
mDisplayHeight = mHeight;
}

RectF surfaceDimensions = new RectF(0,0,mDisplayWidth,mDisplayHeight);
Matrix matrix = new Matrix();
matrix.setRectToRect(previewRect, surfaceDimensions, Matrix.ScaleToFit.FILL);
textureView.setTransform(matrix);
Camera.Parameters param = camera.getParameters();
int displayRotation = 0;

        WindowManager windowManager = (WindowManager) MainActivity.this
                .getSystemService(Context.WINDOW_SERVICE);
int rotation = windowManager.getDefaultDisplay().getRotation();


        switch (rotation) {
            case Surface.ROTATION_0:
             displayRotation =  0;
             break;
            case Surface.ROTATION_90:
             displayRotation =  90;
             break;
            case Surface.ROTATION_180:
             displayRotation =  180;
             break;
            case Surface.ROTATION_270:
             displayRotation =  270;
             break;
        }        

Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(0, info);

if(info.facing == Camera.CameraInfo.CAMERA_FACING_BACK){
orientation = (info.orientation - displayRotation + 360)% 360;
} else {  
orientation = (info.orientation + displayRotation)% 360;
orientation = (360 - orientation) % 360;
}

param.setPreviewSize(mPreviewWidth, mPreviewHeight);
camera.setParameters(param);
camera.setDisplayOrientation(orientation);
try {
camera.setPreviewTexture(surface);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
}


@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
return true;
}


@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int width,
int height) {
// TODO Auto-generated method stub
}


@Override
public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
// TODO Auto-generated method stub
}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在TextureView中实现动画渐变效果,可以使用属性动画(Property Animation)。具体步骤如下: 1. 创建一个ValueAnimator动画对象,设置动画的起始值和结束值。 2. 在动画的更新监听器中,获取当前的动画进度值,计算出需要设置的变换矩阵。 3. 调用TextureViewsetTransform()方法,设置计算出的变换矩阵。 4. 在ValueAnimator对象中设置动画的时长、插值器和监听器等属性。 例如,以下代码演示了在TextureView中实现透明度渐变的动画效果: ```java ValueAnimator alphaAnimator = ValueAnimator.ofFloat(0f, 1f); alphaAnimator.setDuration(1000); alphaAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float alpha = (float) animation.getAnimatedValue(); Matrix matrix = new Matrix(); matrix.setAlpha(alpha); textureView.setTransform(matrix); } }); alphaAnimator.start(); ``` 在上述代码中,创建了一个ValueAnimator对象,设置了动画的起始值为0,结束值为1,时长为1000毫秒,插值器为AccelerateDecelerateInterpolator。 在动画更新监听器中,获取当前的动画进度值alpha,创建一个矩阵对象matrix,并调用setAlpha()方法设置透明度,最后调用textureViewsetTransform()方法设置变换矩阵。 最后调用alphaAnimator的start()方法启动动画即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值