写低版本UVCCamera的类,继续承接UVCCameraTextureView类上面扩展出一个类支持多点触摸支持放大缩小和旋转的类,并解决决定放大旋转中闪屏问题
时间: 2023-11-22 10:56:38 浏览: 25
以下是一个简单的示例代码,展示了如何继承UVCCameraTextureView类并添加多点触摸支持,以及解决放大旋转中的闪屏问题。
```
public class MultiTouchUVCCameraTextureView extends UVCCameraTextureView {
private float mLastTouchX, mLastTouchY;
private int mActivePointerId1 = -1, mActivePointerId2 = -1;
private float mPrevDistance;
private float mPrevRotation;
private boolean mIsZooming, mIsRotating;
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastTouchX = event.getX();
mLastTouchY = event.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() == 2) {
mActivePointerId1 = event.getPointerId(0);
mActivePointerId2 = event.getPointerId(1);
mPrevDistance = getDistance(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
mPrevRotation = getRotation(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
mIsZooming = true;
mIsRotating = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() == 1) {
final float x = event.getX();
final float y = event.getY();
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mLastTouchX = x;
mLastTouchY = y;
// do something with dx and dy, such as moving the camera preview
} else if (event.getPointerCount() == 2) {
final int index1 = event.findPointerIndex(mActivePointerId1);
final int index2 = event.findPointerIndex(mActivePointerId2);
if (index1 != -1 && index2 != -1) {
final float distance = getDistance(event.getX(index1), event.getY(index1), event.getX(index2), event.getY(index2));
final float rotation = getRotation(event.getX(index1), event.getY(index1), event.getX(index2), event.getY(index2));
final float scaleFactor = distance / mPrevDistance;
final float rotationDelta = rotation - mPrevRotation;
mPrevDistance = distance;
mPrevRotation = rotation;
if (mIsZooming) {
// do something with scaleFactor, such as zooming in/out
}
if (mIsRotating) {
// do something with rotationDelta, such as rotating the camera preview
}
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerCount() == 2) {
final int pointerId = event.getPointerId(event.getActionIndex());
if (pointerId == mActivePointerId1 || pointerId == mActivePointerId2) {
if (mIsZooming) {
mIsZooming = false;
}
if (mIsRotating) {
mIsRotating = false;
}
if (pointerId == mActivePointerId1) {
mActivePointerId1 = mActivePointerId2;
}
mActivePointerId2 = -1;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mActivePointerId1 = -1;
mActivePointerId2 = -1;
mIsZooming = false;
mIsRotating = false;
break;
}
return true;
}
private static float getDistance(float x1, float y1, float x2, float y2) {
final float dx = x2 - x1;
final float dy = y2 - y1;
return (float) Math.sqrt(dx * dx + dy * dy);
}
private static float getRotation(float x1, float y1, float x2, float y2) {
final float dx = x2 - x1;
final float dy = y2 - y1;
final double radians = Math.atan2(dy, dx);
return (float) Math.toDegrees(radians);
}
}
```
为了解决放大旋转中的闪屏问题,我们可以使用一个临时的Bitmap来保存当前的画面,并在每次进行放大旋转操作后重新绘制这个Bitmap。以下是修改后的代码:
```
public class MultiTouchUVCCameraTextureView extends UVCCameraTextureView {
private float mLastTouchX, mLastTouchY;
private int mActivePointerId1 = -1, mActivePointerId2 = -1;
private float mPrevDistance;
private float mPrevRotation;
private boolean mIsZooming, mIsRotating;
private Bitmap mTempBitmap;
public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastTouchX = event.getX();
mLastTouchY = event.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() == 2) {
mActivePointerId1 = event.getPointerId(0);
mActivePointerId2 = event.getPointerId(1);
mPrevDistance = getDistance(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
mPrevRotation = getRotation(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
mIsZooming = true;
mIsRotating = true;
mTempBitmap = getBitmap();
}
break;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() == 1) {
final float x = event.getX();
final float y = event.getY();
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mLastTouchX = x;
mLastTouchY = y;
// do something with dx and dy, such as moving the camera preview
} else if (event.getPointerCount() == 2) {
final int index1 = event.findPointerIndex(mActivePointerId1);
final int index2 = event.findPointerIndex(mActivePointerId2);
if (index1 != -1 && index2 != -1) {
final float distance = getDistance(event.getX(index1), event.getY(index1), event.getX(index2), event.getY(index2));
final float rotation = getRotation(event.getX(index1), event.getY(index1), event.getX(index2), event.getY(index2));
final float scaleFactor = distance / mPrevDistance;
final float rotationDelta = rotation - mPrevRotation;
mPrevDistance = distance;
mPrevRotation = rotation;
if (mIsZooming) {
// do something with scaleFactor, such as zooming in/out
}
if (mIsRotating) {
rotateBitmap(rotationDelta);
}
invalidate();
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerCount() == 2) {
final int pointerId = event.getPointerId(event.getActionIndex());
if (pointerId == mActivePointerId1 || pointerId == mActivePointerId2) {
if (mIsZooming) {
mIsZooming = false;
}
if (mIsRotating) {
mIsRotating = false;
}
if (pointerId == mActivePointerId1) {
mActivePointerId1 = mActivePointerId2;
}
mActivePointerId2 = -1;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mActivePointerId1 = -1;
mActivePointerId2 = -1;
mIsZooming = false;
mIsRotating = false;
break;
}
return true;
}
private void rotateBitmap(float degrees) {
// create a new Bitmap with the same size as the TextureView
if (mTempBitmap == null) {
mTempBitmap = getBitmap();
}
final Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
// rotate the canvas around the center of the TextureView
final float centerX = getWidth() / 2f;
final float centerY = getHeight() / 2f;
canvas.rotate(degrees, centerX, centerY);
// draw the temporary Bitmap onto the canvas
canvas.drawBitmap(mTempBitmap, 0, 0, null);
mTempBitmap = bitmap;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mTempBitmap != null) {
canvas.drawBitmap(mTempBitmap, 0, 0, null);
}
}
private static float getDistance(float x1, float y1, float x2, float y2) {
final float dx = x2 - x1;
final float dy = y2 - y1;
return (float) Math.sqrt(dx * dx + dy * dy);
}
private static float getRotation(float x1, float y1, float x2, float y2) {
final float dx = x2 - x1;
final float dy = y2 - y1;
final double radians = Math.atan2(dy, dx);
return (float) Math.toDegrees(radians);
}
}
```
请注意,这只是一个简单的示例代码,可能需要根据具体需求进行修改和优化。