я пытаюсь кодировать в Android Студийная передняя и задняя камеры одновременно, но мое кодирование использует только одну сторону, что мне нужно изменить или добавить кодирование?
Я надеюсь, что кто-то поможет мне
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class CameraTest003 extends AppCompatActivity {
private SurfaceView mSurfaceView,mSurfaceView02;
private SurfaceHolder mSurfaceViewHolder,mSurfaceViewHolder02;
private Handler mHandler,mHandler02;
private ImageReader mImageReader,mImageReader02;
private CameraDevice mCameraDevice,mCameraDevice02;
private CaptureRequest.Builder mPreviewBuilder,mPreviewBuilder02;
private CameraCaptureSession mSession,mSession02;
private int mDeviceRotation;
private Sensor mAccelerometer;
private Sensor mMagnetometer;
private SensorManager mSensorManager;
private DeviceOrientation deviceOrientation;
int mDSI_height, mDSI_width;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(ExifInterface.ORIENTATION_NORMAL, 0);
ORIENTATIONS.append(ExifInterface.ORIENTATION_ROTATE_90, 90);
ORIENTATIONS.append(ExifInterface.ORIENTATION_ROTATE_180, 180);
ORIENTATIONS.append(ExifInterface.ORIENTATION_ROTATE_270, 270);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.camratest001);
ImageButton button = findViewById(R.id.take_photo);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePicture();
}
});
mSurfaceView = findViewById(R.id.surfaceView);
mSurfaceView02 = findViewById(R.id.surfaceViewvideo);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
deviceOrientation = new DeviceOrientation();
initSurfaceView();
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(deviceOrientation.getEventListener(), mAccelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(deviceOrientation.getEventListener(), mMagnetometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(deviceOrientation.getEventListener());
}
public void initSurfaceView() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mDSI_height = 300;
mDSI_width = 300;
mSurfaceViewHolder = mSurfaceView.getHolder();
mSurfaceViewHolder02 = mSurfaceView02.getHolder();
mSurfaceViewHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCameraAndPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
mSurfaceViewHolder02.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCameraAndPreview02();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCameraDevice02 != null) {
mCameraDevice02.close();
mCameraDevice02 = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
}
@androidx.annotation.RequiresApi(api = android.os.Build.VERSION_CODES.LOLLIPOP)
public void initCameraAndPreview() {
HandlerThread handlerThread = new HandlerThread("CAMERA2");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
Handler mainHandler = new Handler(getMainLooper());
try {
String mCameraId = "" + CameraCharacteristics.LENS_FACING_FRONT;
CameraManager mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size largestPreviewSize = map.getOutputSizes(ImageFormat.JPEG)[0];
Log.i("LargestSize", largestPreviewSize.getWidth() + " " + largestPreviewSize.getHeight());
//카메라 프리뷰
setAspectRatioTextureView(largestPreviewSize.getHeight(),largestPreviewSize.getWidth());
mImageReader = ImageReader.newInstance(largestPreviewSize.getWidth(), largestPreviewSize.getHeight(), ImageFormat.JPEG,/*maxImages*/7);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mainHandler);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(mCameraId, deviceStateCallback, mHandler);
} catch (CameraAccessException e) {
Toast.makeText(this, "카메라를 열지 못했습니다.", Toast.LENGTH_SHORT).show();
}
}
@androidx.annotation.RequiresApi(api = android.os.Build.VERSION_CODES.LOLLIPOP)
public void initCameraAndPreview02() {
HandlerThread handlerThread02 = new HandlerThread("CAMERA2");
handlerThread02.start();
mHandler = new Handler(handlerThread02.getLooper());
Handler mainHandler02 = new Handler(getMainLooper());
try {
String mCameraId02 = "" + CameraCharacteristics.LENS_FACING_FRONT;
CameraManager mCameraManager02 = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics02 = mCameraManager02.getCameraCharacteristics(mCameraId02);
StreamConfigurationMap map02 = characteristics02.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size largestPreviewSize02 = map02.getOutputSizes(ImageFormat.JPEG)[0];
//카메라 프리뷰
setAspectRatioTextureView02(largestPreviewSize02.getHeight(),largestPreviewSize02.getWidth());
mImageReader02 = ImageReader.newInstance(largestPreviewSize02.getWidth(), largestPreviewSize02.getHeight(), ImageFormat.JPEG,/*maxImages*/7);
mImageReader02.setOnImageAvailableListener(mOnImageAvailableListener02, mainHandler02);
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager02.openCamera(mCameraId02, deviceStateCallback02, mHandler02);
} catch (CameraAccessException e) {
Toast.makeText(this, "카메라를 열지 못했습니다.", Toast.LENGTH_SHORT).show();
}
}
private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
new CameraTest003.SaveImageTask().execute(bitmap);
}
};
private ImageReader.OnImageAvailableListener mOnImageAvailableListener02 = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader02) {
Image image02 = reader02.acquireNextImage();
ByteBuffer buffer02 = image02.getPlanes()[0].getBuffer();
byte[] bytes02 = new byte[buffer02.remaining()];
buffer02.get(bytes02);
final Bitmap bitmap02 = BitmapFactory.decodeByteArray(bytes02, 0, bytes02.length);
new CameraTest003.SaveImageTask().execute(bitmap02);
}
};
private CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
try {
takePreview();
} catch (CameraAccessException e) {
//e.printStackTrace();
}
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(CameraDevice camera, int error) {
Toast.makeText(CameraTest003.this, "카메라를 열지 못했습니다.", Toast.LENGTH_SHORT).show();
}
};
private CameraDevice.StateCallback deviceStateCallback02 = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera02) {
mCameraDevice02 = camera02;
try {
takePreview02();
} catch (CameraAccessException e) {
// e.printStackTrace();
}
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
if (mCameraDevice02 != null) {
mCameraDevice02.close();
mCameraDevice02 = null;
}
}
@Override
public void onError(CameraDevice camera, int error) {
Toast.makeText(CameraTest003.this, "카메라를 열지 못했습니다.2", Toast.LENGTH_SHORT).show();
}
};
public void takePreview() throws CameraAccessException {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder.addTarget(mSurfaceViewHolder.getSurface());
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceViewHolder.getSurface(), mImageReader.getSurface()), mSessionPreviewStateCallback, mHandler);
}
public void takePreview02() throws CameraAccessException {
mPreviewBuilder02 = mCameraDevice02.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder02.addTarget(mSurfaceViewHolder02.getSurface());
mCameraDevice02.createCaptureSession(Arrays.asList(mSurfaceViewHolder02.getSurface(), mImageReader02.getSurface()), mSessionPreviewStateCallback02, mHandler02);
}
private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mSession = session;
try {
mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(CameraTest003.this, "카메라 구성 실패", Toast.LENGTH_SHORT).show();
}
};
private CameraCaptureSession.StateCallback mSessionPreviewStateCallback02 = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mSession02= session;
try {
mPreviewBuilder02.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewBuilder02.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mSession02.setRepeatingRequest(mPreviewBuilder02.build(), null, mHandler02);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Toast.makeText(CameraTest003.this, "카메라 구성 실패2", Toast.LENGTH_SHORT).show();
}
};
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
mSession = session;
unlockFocus();
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
mSession = session;
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
};
public void takePicture() {
try {
CaptureRequest.Builder captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);//用来设置拍照请求的request
captureRequestBuilder.addTarget(mImageReader.getSurface());
captureRequestBuilder.addTarget(mImageReader02.getSurface());
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
//deviceRotation = getResources().getConfiguration().orientation;
mDeviceRotation = ORIENTATIONS.get(deviceOrientation.getOrientation());
Log.d("@@@", mDeviceRotation+"");
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mDeviceRotation);
CaptureRequest mCaptureRequest = captureRequestBuilder.build();
mSession.capture(mCaptureRequest, mSessionCaptureCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
public Bitmap getRotatedBitmap(Bitmap bitmap, int degrees) throws Exception {
if(bitmap == null) return null;
if (degrees == 0) return bitmap;
Matrix m = new Matrix();
m.setRotate(degrees, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mSession.capture(mPreviewBuilder.build(), mSessionCaptureCallback,
mHandler);
// After this, the camera will go back to the normal state of preview.
mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback,
mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
public static final String insertImage(ContentResolver cr,
Bitmap source,
String title,
String description) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, title);
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
values.put(MediaStore.Images.Media.DESCRIPTION, description);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
} finally {
imageOut.close();
}
} else {
cr.delete(url, null, null);
url = null;
}
} catch (Exception e) {
if (url != null) {
cr.delete(url, null, null);
url = null;
}
}
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
private class SaveImageTask extends AsyncTask<Bitmap, Void, Void> {
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(CameraTest003.this, "사진을 저장하였습니다.", Toast.LENGTH_SHORT).show();
}
@Override
protected Void doInBackground(Bitmap... data) {
Bitmap bitmap = null;
try {
bitmap = getRotatedBitmap(data[0], mDeviceRotation);
} catch (Exception e) {
e.printStackTrace();
}
insertImage(getContentResolver(), bitmap, ""+System.currentTimeMillis(), "");
return null;
}
}
// 출처 https://stackoverflow.com/a/43516672
//카메라 프리뷰 함수
private void setAspectRatioTextureView(int ResolutionWidth , int ResolutionHeight )
{
if(ResolutionWidth > ResolutionHeight){
int newWidth = mDSI_width;
int newHeight = ((mDSI_width * ResolutionWidth)/ResolutionHeight);
updateTextureViewSize(newWidth,newHeight);
}else {
int newWidth = mDSI_width;
int newHeight = ((mDSI_width * ResolutionHeight)/ResolutionWidth);
updateTextureViewSize(newWidth,newHeight);
}
}
private void setAspectRatioTextureView02(int ResolutionWidth , int ResolutionHeight )
{
if(ResolutionWidth > ResolutionHeight){
int newWidth = mDSI_width;
int newHeight = ((mDSI_width * ResolutionWidth)/ResolutionHeight);
updateTextureViewSize(newWidth,newHeight);
}else {
int newWidth = mDSI_width;
int newHeight = ((mDSI_width * ResolutionHeight)/ResolutionWidth);
updateTextureViewSize(newWidth,newHeight);
}
}
private void updateTextureViewSize(int viewWidth, int viewHeight) {
Log.d("@@@", "TextureView Width : " + viewWidth + " TextureView Height : " + viewHeight);
mSurfaceView.setLayoutParams(new FrameLayout.LayoutParams(viewWidth, viewHeight));
}
public class DeviceOrientation {
private final int ORIENTATION_PORTRAIT = ExifInterface.ORIENTATION_ROTATE_90; // 6
private final int ORIENTATION_LANDSCAPE_REVERSE = ExifInterface.ORIENTATION_ROTATE_180; // 3
private final int ORIENTATION_LANDSCAPE = ExifInterface.ORIENTATION_NORMAL; // 1
private final int ORIENTATION_PORTRAIT_REVERSE = ExifInterface.ORIENTATION_ROTATE_270; // 8
int smoothness = 1;
private float averagePitch = 0;
private float averageRoll = 0;
private int orientation = ORIENTATION_PORTRAIT;
private float[] pitches;
private float[] rolls;
public DeviceOrientation() {
pitches = new float[smoothness];
rolls = new float[smoothness];
}
public SensorEventListener getEventListener() {
return sensorEventListener;
}
public int getOrientation() {
return orientation;
}
SensorEventListener sensorEventListener = new SensorEventListener() {
float[] mGravity;
float[] mGeomagnetic;
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientationData[] = new float[3];
SensorManager.getOrientation(R, orientationData);
averagePitch = addValue(orientationData[1], pitches);
averageRoll = addValue(orientationData[2], rolls);
orientation = calculateOrientation();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
private float addValue(float value, float[] values) {
value = (float) Math.round((Math.toDegrees(value)));
float average = 0;
for (int i = 1; i < smoothness; i++) {
values[i - 1] = values[i];
average += values[i];
}
values[smoothness - 1] = value;
average = (average + value) / smoothness;
return average;
}
private int calculateOrientation() {
// finding local orientation dip
if (((orientation == ORIENTATION_PORTRAIT || orientation == ORIENTATION_PORTRAIT_REVERSE)
&& (averageRoll > -30 && averageRoll < 30))) {
if (averagePitch > 0)
return ORIENTATION_PORTRAIT_REVERSE;
else
return ORIENTATION_PORTRAIT;
} else {
// divides between all orientations
if (Math.abs(averagePitch) >= 30) {
if (averagePitch > 0)
return ORIENTATION_PORTRAIT_REVERSE;
else
return ORIENTATION_PORTRAIT;
} else {
if (averageRoll > 0) {
return ORIENTATION_LANDSCAPE_REVERSE;
} else {
return ORIENTATION_LANDSCAPE;
}
}
}
}
}
я не знаю, как я могу сделать