我正在制作一个 android studio 应用程序,它必须在 Android 11(API30)上显示外部摄像头的视频图像。
我对 android studio 和 java 完全陌生。我设法用 chatgpt 从头开始写了一个预览 surfaceview,因为关于这个问题的教程不多。我现在正在研究缩放按钮,但我尝试的一切都不起作用。我做了一个 zoomthread 在后台运行但是当我在预览中按下缩放按钮时没有任何反应。
package com.example.concept3;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CaptureRequest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private CameraCaptureSession captureSession;
private Button zoomButton;
private CaptureRequest.Builder builder;
private CameraCharacteristics characteristics;
String[] cameraIds;
String cameraId;
private int zoomLevel;
private static final int REQUEST_CAMERA_PERMISSION = 44;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try{
cameraIds = cameraManager.getCameraIdList();
cameraId = cameraIds[0];
cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
//camera configuratie
try {
builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
SurfaceView surfaceView = findViewById(R.id.Beeld);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
try {
Surface surface = holder.getSurface();
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surface);
List<Surface> outputSurface = new ArrayList<>(10000 );
outputSurface.add(surface);
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
try {
builder.addTarget(surface);
CaptureRequest request = builder.build();
captureSession.setRepeatingRequest(request, null, null);
zoomButton = findViewById(R.id.zoomButton);
zoomButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cameraDevice != null){
Handler handler = new Handler(Looper.getMainLooper());
zoomThread thread = new zoomThread(cameraDevice, zoomLevel, cameraManager, builder, characteristics, surfaceView.getHolder().getSurface(), handler);
thread.start();
}
}
});
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
captureSession.close();
captureSession = null;
}
});
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
cameraDevice.close();
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int i) {
cameraDevice.close();
}
}, null);
} catch (CameraAccessException e){
e.printStackTrace();
}
}
public class zoomThread extends Thread {
private CameraDevice cameraDevice;
private int zoomLevel;
private CameraManager cameraManager;
private CaptureRequest.Builder builder;
private CameraCharacteristics characteristics;
private Surface previewSurface;
private Handler handler;
float newZoom = 2.0f;
public zoomThread(CameraDevice cameraDevice, int zoomLevel, CameraManager cameraManager, CaptureRequest.Builder builder, CameraCharacteristics characteristics, Surface previewSurface, Handler handler){
this.zoomLevel = zoomLevel;
this.cameraDevice = cameraDevice;
this.cameraManager = cameraManager;
this.builder = builder;
this.characteristics = characteristics;
this.previewSurface = previewSurface;
this.handler = handler;
}
@Override
public void run() {
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
characteristics = cameraManager.getCameraCharacteristics(cameraId);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
float maxZoom = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
if (zoomLevel <= maxZoom){
Rect activeRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
int centerX = activeRect.centerX();
int centerY = activeRect.centerY();
int deltaX = (int) ((0.5f * activeRect.width() / newZoom));
int deltaY = (int) ((0.5f * activeRect.height() / newZoom));
Rect newRect = new Rect(centerX - deltaX, centerY - deltaY, centerX + deltaX, centerY + deltaY);
builder.set(CaptureRequest.SCALER_CROP_REGION, newRect);
List<Surface> outputSurfaces = new ArrayList<Surface>();
outputSurfaces.add(previewSurface);
try {
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
CaptureRequest captureRequest = builder.build();
try {
session.setRepeatingRequest(captureRequest, null, null);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
},handler);
} catch (CameraAccessException e) {
throw new RuntimeException(e);
}
}
}
}
}