返回
深入浅出,相机预览及简单滤镜开发详解
Android
2023-09-02 17:56:28
相机预览
相机预览是指将摄像头的实时画面显示在屏幕上。实现相机预览的基本原理是:摄像头采集图像数据,然后将这些数据传输给图像处理单元,图像处理单元对图像数据进行处理,最后将处理后的图像数据显示在屏幕上。
相机预览及简单滤镜开发
接下来,我们将详细讲解如何使用Opengles进行相机预览并添加滤镜。
1. 准备工作
在开始开发之前,我们需要准备以下工具和材料:
- Android Studio
- OpenCV库
- EGL库
- GLES库
2. 创建Android项目
首先,我们需要创建一个新的Android项目。打开Android Studio,点击“新建项目”,然后选择“空项目”。在“项目名称”中输入项目的名称,在“包名称”中输入项目的包名,然后点击“下一步”。
3. 添加依赖项
接下来,我们需要添加OpenCV库、EGL库和GLES库的依赖项。在Android Studio的“项目结构”窗口中,点击“依赖项”选项卡,然后点击“添加依赖项”。在“依赖项”对话框中,选择“库依赖项”,然后搜索OpenCV库、EGL库和GLES库。找到这些库后,点击“确定”按钮。
4. 创建相机预览Activity
接下来,我们需要创建一个相机预览Activity。在Android Studio中,右键点击项目的包名,然后选择“新建” > “Activity” > “空Activity”。在“Activity名称”中输入Activity的名称,然后点击“完成”按钮。
5. 实现相机预览
接下来,我们需要实现相机预览功能。在相机预览Activity的Java文件中,添加以下代码:
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import org.opencv.android.OpenCVLoader;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class CameraPreviewActivity extends AppCompatActivity {
private static final String TAG = "CameraPreviewActivity";
private TextureView mTextureView;
private Button mButton;
private CameraManager mCameraManager;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCameraCaptureSession;
private ImageReader mImageReader;
private Surface mSurface;
private boolean mIsPreviewing = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_preview);
mTextureView = (TextureView) findViewById(R.id.textureView);
mButton = (Button) findViewById(R.id.button);
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
// 申请相机权限
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 100);
return;
}
// 打开相机
try {
String[] cameraIds = mCameraManager.getCameraIdList();
for (String cameraId : cameraIds) {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
mCameraManager.openCamera(cameraId, mStateCallback, null);
break;
}
}
} catch (CameraAccessException e) {
Log.e(TAG, "打开相机失败", e);
}
// 创建ImageReader
mImageReader = ImageReader.newInstance(640, 480, ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image != null) {
// 处理图像数据
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
// 释放图像
image.close();
}
}
}, null);
// 创建SurfaceTexture
mSurfaceTexture = new SurfaceTexture(100);
mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// 更新纹理视图
mTextureView.updateViewLayout(mTextureView.getWidth(), mTextureView.getHeight());
mTextureView.invalidate();
}
});
// 创建Surface
mSurface = new Surface(mSurfaceTexture);
// 创建CaptureRequest
CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(mSurface);
builder.addTarget(mImageReader.getSurface());
// 创建CameraCaptureSession
mCameraDevice.createCaptureSession(Arrays.asList(mSurface, mImageReader.getSurface()), mSessionCallback, null);
}
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
mCameraDevice = camera;
mIsPreviewing = true;
// 启动预览
mCameraDevice.createCaptureSession(Arrays.asList(mSurface, mImageReader.getSurface()), mSessionCallback, null);
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
mIsPreviewing = false;
mCameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
mIsPreviewing = false;
mCameraDevice.close();
mCameraDevice = null;
}
};
private CameraCaptureSession.StateCallback mSessionCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mCameraCaptureSession = session;
// 设置自动对焦
CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(mSurface);
builder.addTarget(mImageReader.getSurface());
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 启动预览
mCameraCaptureSession.setRepeatingRequest(builder.build(), null, null);
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Log.e(TAG, "配置CameraCaptureSession失败");
}
};
@Override
protected void onResume() {
super.onResume();
if (OpenCVLoader.initDebug()) {
Log.i(TAG, "OpenCV加载成功");
} else {
Log.e(TAG, "OpenCV加载失败");
}
if (!mIsPreviewing) {
// 重新打开相机
try {
String[] cameraIds = mCameraManager.getCameraIdList();
for (String cameraId : cameraIds) {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
mCameraManager.openCamera(