SurfaceView 中绘制预览画面时进行镜像翻转
时间: 2024-05-16 07:17:43 浏览: 6
在 SurfaceView 中绘制预览画面时进行镜像翻转,需要对绘制的 Bitmap 进行处理。可以使用 Matrix 类的 setScale() 方法进行缩放,再使用 postTranslate() 方法进行平移,最后将处理后的 Bitmap 绘制到 SurfaceView 上即可实现镜像翻转。
具体实现步骤如下:
1. 获取相机预览数据,转换成 Bitmap 对象;
2. 创建一个 Matrix 对象,使用 setScale() 方法设置水平缩放比例为 -1,垂直缩放比例为 1,也就是进行水平镜像翻转;
3. 使用 postTranslate() 方法对 Bitmap 进行平移,将其向左平移一个图片宽度的距离,这样可以使得镜像翻转后的图片显示在 SurfaceView 的左侧;
4. 将处理后的 Bitmap 绘制到 SurfaceView 上。
以下是代码示例:
```java
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(parameters, width, height);
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
// 获取相机预览数据,转换成 Bitmap 对象
byte[] data = new byte[width * height * 3 / 2];
mCamera.addCallbackBuffer(data);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Bitmap bitmap = YuvUtil.yuv2Bitmap(data, width, height);
if (bitmap != null) {
// 创建一个 Matrix 对象,使用 setScale() 方法设置水平缩放比例为 -1,垂直缩放比例为 1
Matrix matrix = new Matrix();
matrix.postScale(-1, 1);
// 使用 postTranslate() 方法对 Bitmap 进行平移,将其向左平移一个图片宽度的距离
matrix.postTranslate(bitmap.getWidth(), 0);
// 将处理后的 Bitmap 绘制到 SurfaceView 上
Canvas canvas = getHolder().lockCanvas();
canvas.drawBitmap(bitmap, matrix, null);
getHolder().unlockCanvasAndPost(canvas);
}
mCamera.addCallbackBuffer(data);
}
});
mCamera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
private Camera.Size getBestPreviewSize(Camera.Parameters parameters, int width, int height) {
Camera.Size bestSize = null;
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
float aspectRatio = (float) width / height;
float minDiff = Float.MAX_VALUE;
for (Camera.Size size : sizes) {
float sizeAspectRatio = (float) size.width / size.height;
float diff = Math.abs(aspectRatio - sizeAspectRatio);
if (diff < minDiff) {
bestSize = size;
minDiff = diff;
}
}
return bestSize;
}
}
```
需要注意的是,这种方式会导致预览画面左右倒置,如果需要将预览画面上下倒置,可以使用 setScale() 方法设置垂直缩放比例为 -1,水平缩放比例为 1,然后使用 postTranslate() 方法将 Bitmap 向上平移一个图片高度的距离。