写一个UVCCamera的类,继承UVCCameraTextureView类上面扩展出一个类支持多点触碰支持放大缩小和旋转的类,并解决闪屏问题
时间: 2023-08-16 18:06:56 浏览: 291
好的,我来写一个继承自UVCCameraTextureView的支持多点触碰、放大缩小和旋转的类,并且解决闪屏问题。
```java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.serenegiant.usb.widget.UVCCameraTextureView;
public class MultiTouchUVCCameraTextureView extends UVCCameraTextureView {
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private static final int ROTATE = 3;
private int mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float oldRotation = 0;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
public MultiTouchUVCCameraTextureView(Context context) {
super(context);
}
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, matrix, null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
oldRotation = rotation(event);
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
float newRotation = rotation(event) - oldRotation;
float scale = newDist / oldDist;
matrix.set(savedMatrix);
matrix.postScale(scale, scale, mid.x, mid.y);
matrix.postRotate(newRotation, mid.x, mid.y);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
invalidate();
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
public void setBitmapMatrix(Matrix matrix) {
this.matrix = matrix;
invalidate();
}
}
```
这个类实现了一个基本的多点触控的图片缩放、旋转和拖拽功能。同时,我们在onDraw()方法中绘制了一个Bitmap,并使用Matrix来控制它的缩放和旋转。最后,在setBitmapMatrix()方法中我们通过传入一个Matrix对象来更新Bitmap的矩阵,从而实现动态的缩放和旋转。
解决闪屏问题:
在UVCCameraTextureView的子类中,我们可以重写surfaceChanged()方法来解决闪屏问题。在surfaceChanged()中,我们可以重新计算预览画面的尺寸,然后调用setFixedSize()方法来设置TextureView的尺寸。这样,在每次预览画面尺寸改变时,我们都能够正确地显示预览画面。
```java
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mCamera == null) {
return;
}
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size previewSize = parameters.getPreviewSize();
float ratio = Math.max((float) width / previewSize.width, (float) height / previewSize.height);
int newWidth = Math.round(previewSize.width * ratio);
int newHeight = Math.round(previewSize.height * ratio);
setFixedSize(newWidth, newHeight);
}
```
阅读全文
相关推荐















