我正在尝试将相机2与Google示例中的AutoFitTextureView一起使用。
我是这样设置的
private void setUpCameraOutputs() {
CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
try {
if (manager != null) {
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// We don't use a front facing camera in this sample.
//noinspection ConstantConditions
if (characteristics.get(LENS_FACING) == LENS_FACING_FRONT) continue;
StreamConfigurationMap map = characteristics.get(SCALER_STREAM_CONFIGURATION_MAP);
if(map != null) {
// For still image captures, we use the largest available size.
List<Size> outputSizes = Arrays.asList(map.getOutputSizes(sImageFormat));
Size largest = Collections.max(outputSizes, new CompareSizesByArea());
mImageReader = ImageReader.newInstance(640, 480, sImageFormat, 8);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
// Danger, W.R.! Attempting to use too large a preview size could exceed the camera
// bus' bandwidth limitation, resulting in gorgeous previews but the storage of
// garbage capture data.
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), largest.getWidth(), largest.getHeight(), largest);
//mPreviewSize = new Size(largest.getWidth(), largest.getHeight());
setAspectRatio2(mPreviewSize);
Logging.e(TAG, "WIDTH: " + mPreviewSize.getWidth() + " HEIGHT: " + mPreviewSize.getHeight());
mCameraId = cameraId;
}
//return;
}
}else{
Logging.e(TAG,"No Manager");
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setAspectRatio(){
int orientation = mContext.getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mTextureView.setAspectRatio(mPreviewSize.getWidth(),mPreviewSize.getHeight());
} else {
mTextureView.setAspectRatio(mPreviewSize.getHeight(),mPreviewSize.getWidth());
}
}
private void setAspectRatio2(Size largest){
float cameraAspectRatio = (float) largest.getHeight() / largest.getWidth();
//Preparation
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE));
wm.getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight = metrics.heightPixels;
int finalWidth = screenWidth;
int finalHeight = screenHeight;
int widthDifference = 0;
int heightDifference = 0;
float screenAspectRatio = (float) screenWidth / screenHeight;
//Determines whether we crop width or crop height
if (screenAspectRatio > cameraAspectRatio) { //Keep width crop height
finalHeight = (int) (screenWidth / cameraAspectRatio);
heightDifference = finalHeight - screenHeight;
} else { //Keep height crop width
finalWidth = (int) (screenHeight * cameraAspectRatio);
widthDifference = finalWidth - screenWidth;
}
//Apply the result to the Preview
LayoutParams lp = (FrameLayout.LayoutParams) mTextureView.getLayoutParams();
lp.width = finalWidth;
lp.height = finalHeight;
//Below 2 lines are to center the preview, since cropping default occurs at the right and bottom
lp.leftMargin = - (widthDifference / 2);
lp.topMargin = - (heightDifference / 2);
mTextureView.setLayoutParams(lp);
}
private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview Surface
List<Size> bigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
double ratio = (double) h / w;
for (Size option : choices) {
double optionRatio = (double) option.getHeight() / option.getWidth();
if (ratio == optionRatio) {
bigEnough.add(option);
}
}
// Pick the smallest of those, assuming we found any
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} else {
Logging.e(TAG, "Couldn't find any suitable preview size");
return choices[1];
}
}
我尝试用2种不同的方法设置纵横比,但是似乎没有一种方法可以满足我的需要。 预览可以根据需要显示所有屏幕,但是相机预览总是显得狭窄,看起来更细。 我已经尝试过一些来自stackoverflow的建议,但是仍然没有得到理想的结果。