|
|
|
@ -1,10 +1,46 @@ |
|
|
|
|
package com.flurgle.camerakit; |
|
|
|
|
|
|
|
|
|
import android.annotation.TargetApi; |
|
|
|
|
import android.content.Context; |
|
|
|
|
import android.graphics.ImageFormat; |
|
|
|
|
import android.hardware.camera2.CameraAccessException; |
|
|
|
|
import android.hardware.camera2.CameraCharacteristics; |
|
|
|
|
import android.hardware.camera2.CameraDevice; |
|
|
|
|
import android.hardware.camera2.CameraManager; |
|
|
|
|
import android.hardware.camera2.params.StreamConfigurationMap; |
|
|
|
|
import android.util.Log; |
|
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.Iterator; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.TreeSet; |
|
|
|
|
|
|
|
|
|
@TargetApi(21) |
|
|
|
|
class Camera2 extends CameraImpl { |
|
|
|
|
|
|
|
|
|
Camera2(CameraListener callback, PreviewImpl preview) { |
|
|
|
|
private CameraDevice mCamera; |
|
|
|
|
private CameraCharacteristics mCameraCharacteristics; |
|
|
|
|
private CameraManager mCameraManager; |
|
|
|
|
|
|
|
|
|
private String mCameraId; |
|
|
|
|
private int mFacing; |
|
|
|
|
|
|
|
|
|
private Size mCaptureSize; |
|
|
|
|
private Size mPreviewSize; |
|
|
|
|
|
|
|
|
|
Camera2(CameraListener callback, PreviewImpl preview, Context context) { |
|
|
|
|
super(callback, preview); |
|
|
|
|
preview.setCallback(new PreviewImpl.Callback() { |
|
|
|
|
@Override |
|
|
|
|
public void onSurfaceChanged() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CameraImpl:
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
void start() { |
|
|
|
@ -23,7 +59,44 @@ class Camera2 extends CameraImpl { |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
void setFacing(@Facing int facing) { |
|
|
|
|
|
|
|
|
|
int internalFacing = new ConstantMapper.Facing(facing).map(); |
|
|
|
|
if (internalFacing == -1) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
final String[] ids; |
|
|
|
|
try { |
|
|
|
|
ids = mCameraManager.getCameraIdList(); |
|
|
|
|
} catch (CameraAccessException e) { |
|
|
|
|
Log.e("CameraKit", e.toString()); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ids.length == 0) { |
|
|
|
|
throw new RuntimeException("No camera available."); |
|
|
|
|
} |
|
|
|
|
//
|
|
|
|
|
// for (String id : ids) {
|
|
|
|
|
// CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(id);
|
|
|
|
|
// Integer level = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
|
|
|
|
|
// if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
// Integer internal = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
|
|
|
|
|
// if (internal == null) {
|
|
|
|
|
// throw new NullPointerException("Unexpected state: LENS_FACING null");
|
|
|
|
|
// }
|
|
|
|
|
// if (internal == internalFacing) {
|
|
|
|
|
// mCameraId = id;
|
|
|
|
|
// mCameraCharacteristics = cameraCharacteristics;
|
|
|
|
|
// return true;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (mFacing == facing && isCameraOpened()) { |
|
|
|
|
stop(); |
|
|
|
|
start(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@ -63,17 +136,95 @@ class Camera2 extends CameraImpl { |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
Size getCaptureResolution() { |
|
|
|
|
return null; |
|
|
|
|
if (mCaptureSize == null && mCameraCharacteristics != null) { |
|
|
|
|
TreeSet<Size> sizes = new TreeSet<>(); |
|
|
|
|
sizes.addAll(getAvailableCaptureResolutions()); |
|
|
|
|
|
|
|
|
|
TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter( |
|
|
|
|
getAvailablePreviewResolutions(), |
|
|
|
|
getAvailableCaptureResolutions() |
|
|
|
|
).filter(); |
|
|
|
|
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null; |
|
|
|
|
|
|
|
|
|
Iterator<Size> descendingSizes = sizes.descendingIterator(); |
|
|
|
|
Size size; |
|
|
|
|
while (descendingSizes.hasNext() && mCaptureSize == null) { |
|
|
|
|
size = descendingSizes.next(); |
|
|
|
|
if (targetRatio == null || targetRatio.matches(size)) { |
|
|
|
|
mCaptureSize = size; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return mCaptureSize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
Size getPreviewResolution() { |
|
|
|
|
return null; |
|
|
|
|
if (mPreviewSize == null && mCameraCharacteristics != null) { |
|
|
|
|
TreeSet<Size> sizes = new TreeSet<>(); |
|
|
|
|
sizes.addAll(getAvailablePreviewResolutions()); |
|
|
|
|
|
|
|
|
|
TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter( |
|
|
|
|
getAvailablePreviewResolutions(), |
|
|
|
|
getAvailableCaptureResolutions() |
|
|
|
|
).filter(); |
|
|
|
|
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null; |
|
|
|
|
|
|
|
|
|
Iterator<Size> descendingSizes = sizes.descendingIterator(); |
|
|
|
|
Size size; |
|
|
|
|
while (descendingSizes.hasNext() && mPreviewSize == null) { |
|
|
|
|
size = descendingSizes.next(); |
|
|
|
|
if (targetRatio == null || targetRatio.matches(size)) { |
|
|
|
|
mPreviewSize = size; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return mPreviewSize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
boolean isCameraOpened() { |
|
|
|
|
return false; |
|
|
|
|
return mCamera != null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Internal
|
|
|
|
|
|
|
|
|
|
private List<Size> getAvailableCaptureResolutions() { |
|
|
|
|
List<Size> output = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
if (mCameraCharacteristics != null) { |
|
|
|
|
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); |
|
|
|
|
if (map == null) { |
|
|
|
|
throw new IllegalStateException("Failed to get configuration map: " + mCameraId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (android.util.Size size : map.getOutputSizes(ImageFormat.JPEG)) { |
|
|
|
|
output.add(new Size(size.getWidth(), size.getHeight())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return output; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private List<Size> getAvailablePreviewResolutions() { |
|
|
|
|
List<Size> output = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
if (mCameraCharacteristics != null) { |
|
|
|
|
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); |
|
|
|
|
if (map == null) { |
|
|
|
|
throw new IllegalStateException("Failed to get configuration map: " + mCameraId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (android.util.Size size : map.getOutputSizes(mPreview.getOutputClass())) { |
|
|
|
|
output.add(new Size(size.getWidth(), size.getHeight())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return output; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|