写一个CameraHelper.setFrameCallback用AppCompatImageView显示摄像头实时图像的例子
时间: 2024-02-23 18:59:24 浏览: 157
好的,以下是一个简单的示例:
```java
public class CameraPreviewActivity extends AppCompatActivity {
private static final int CAMERA_PERMISSION_REQUEST_CODE = 100;
private Camera camera;
private CameraPreview cameraPreview;
private AppCompatImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_preview);
imageView = findViewById(R.id.imageView);
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
} else {
startCameraPreview();
}
}
private void startCameraPreview() {
camera = Camera.open();
cameraPreview = new CameraPreview(this, camera);
FrameLayout previewLayout = findViewById(R.id.cameraPreviewLayout);
previewLayout.addView(cameraPreview);
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Bitmap bitmap = getBitmapFromCameraData(data, camera);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
});
}
private Bitmap getBitmapFromCameraData(byte[] data, Camera camera) {
Camera.Size size = camera.getParameters().getPreviewSize();
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, size.width, size.height), 100, outputStream);
byte[] jpegData = outputStream.toByteArray();
return BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startCameraPreview();
} else {
Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (camera != null) {
camera.stopPreview();
camera.release();
}
}
}
```
在这个例子中,我们使用了一个 `CameraPreview` 自定义 View 来显示相机预览,它的代码如下:
```java
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder holder;
public CameraPreview(Context context, Camera camera) {
super(context);
this.camera = camera;
this.holder = getHolder();
this.holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return result;
}
}
```
`CameraPreview` 显示相机预览,并且在每次预览帧数据可用时,将数据转换为 Bitmap 并设置到 ImageView 中。
需要注意的是,这个例子中的代码比较简单,没有做一些必要的错误处理和异常处理,实际开发中需要根据具体情况进行调整。
阅读全文
相关推荐


















