我正在努力尝试在Camera2下使用缩放功能。该API并不是很有帮助,它必须要说出来,而其他类库(例如CameraKit)并不能满足我的要求。 我已经看过了该网站和其他网站上的各种代码,并提出了以下内容,但是我什么都做不了-甚至没有TextureView上相机的提要。 (我对保存相机中的图像不感兴趣,只是为了显示和捏缩放)。这不是权限的问题,因为我被问到是否允许摄像机访问,只是什么也没出现。
布局xml文件的相关部分如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frlayout"
android:layout_weight="0.80"
android:layout_width="match_parent"
android:layout_height="0dp">
<TextureView
android:id="@+id/cameraView"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true" />
</FrameLayout>
主要活动的主要部分在这里:
public class MainActivity extends AppCompatActivity {
public float finger_spacing = 0;
public int zoom_level = 1;
String camerId;
CameraCharacteristics characteristics;
int PERMISSION_ALL = 1;
private Size previewsize;
private Size jpegSizes[]=null;
private TextureView textureView;
private CameraDevice cameraDevice;
private CaptureRequest.Builder previewBuilder;
private CameraCaptureSession previewSession;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_ALL);
}
textureView=(TextureView)findViewById(R.id.cameraView);
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
public void openCamera()
{
CameraManager manager=(CameraManager)getSystemService(Context.CAMERA_SERVICE);
try
{
camerId=manager.getCameraIdList()[0];
characteristics=manager.getCameraCharacteristics(camerId);
StreamConfigurationMap map=characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewsize=map.getOutputSizes(SurfaceTexture.class)[0];
if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
manager.openCamera(camerId, stateCallback, null);
}
}catch (Exception e)
{
}
}
private TextureView.SurfaceTextureListener surfaceTextureListener=new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private CameraDevice.StateCallback stateCallback=new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
cameraDevice=camera;
startCamera();
// With previewBuilder set up, we can now call the fn to initialise ontouch
setuptexturetouch();
}
@Override
public void onDisconnected(CameraDevice camera) {
}
@Override
public void onError(CameraDevice camera, int error) {
}
};
@Override
protected void onPause() {
super.onPause();
if(cameraDevice!=null)
{
cameraDevice.close();
}
}
void startCamera()
{
if(cameraDevice==null||!textureView.isAvailable()|| previewsize==null)
{
return;
}
SurfaceTexture texture=textureView.getSurfaceTexture();
if(texture==null)
{
return;
}
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
Surface surface=new Surface(texture);
//mPreviewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//mPreviewRequestBuilder.addTarget(surface);
try
{
previewBuilder=cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
}catch (Exception e)
{
}
previewBuilder.addTarget(surface);
try
{
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
previewSession=session;
getChangedPreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
},null);
}catch (Exception e)
{
}
}
void getChangedPreview()
{
if(cameraDevice==null)
{
return;
}
previewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
HandlerThread thread=new HandlerThread("changed Preview");
thread.start();
Handler handler=new Handler(thread.getLooper());
try
{
previewSession.setRepeatingRequest(previewBuilder.build(), null, handler);
}catch (Exception e){}
}
void setuptexturetouch()
{
textureView.setOnTouchListener( new View.OnTouchListener()
{
@Override
public boolean onTouch( View v, MotionEvent event )
{
try {
Activity activity = MainActivity.this;
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(camerId);
}
catch(Exception e)
{
}
float maxzoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10;
Rect m = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
int action = event.getAction();
float current_finger_spacing;
if (event.getPointerCount() > 1)
{
// Multi touch logic
current_finger_spacing = getFingerSpacing(event);
if(finger_spacing != 0){
if(current_finger_spacing > finger_spacing && maxzoom > zoom_level){
zoom_level++;
} else if (current_finger_spacing < finger_spacing && zoom_level > 1){
zoom_level--;
}
int minW = (int) (m.width() / maxzoom);
int minH = (int) (m.height() / maxzoom);
int difW = m.width() - minW;
int difH = m.height() - minH;
int cropW = difW /100 *(int)zoom_level;
int cropH = difH /100 *(int)zoom_level;
cropW -= cropW & 3;
cropH -= cropH & 3;
Rect zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
previewBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
}
finger_spacing = current_finger_spacing;
}
else
{
if (action == MotionEvent.ACTION_UP)
{
//single touch logic
}
}
try
{
previewSession.setRepeatingRequest(previewBuilder.build(), mCaptureCallback, null);
}
catch (CameraAccessException e)
{
//e.printStackTrace();
}
catch (NullPointerException ex)
{
//ex.printStackTrace();
}
}
catch (Exception e)
{
//throw new RuntimeException("can not access camera.", e);
}
return true;
}
});
}
private float getFingerSpacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback()
{
private void process(CaptureResult result)
{
// Just a placeholder at present - the original code
// had switch statements to see if an image had been saved
// but I only want to view, not save.
}
@Override
public void onCaptureProgressed(CameraCaptureSession session,
CaptureRequest request,
CaptureResult partialResult) {
process(partialResult);
}
@Override
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
process(result);
}
};
}