Как получить Android-камеру2 с соотношением 1: 1, например Instagram?

Мой вопрос очень прост:

Как получить Android android.hardware.Camera2 с соотношением 1: 1 и без деформации, такой как Instagram?

Я тестировал проект GoogeSamples android-Camera2Basic . Но когда я меняю предварительный просмотр с соотношением 1: 1, изображение деформируется. У кого-нибудь есть идея по этому поводу?

Введите описание изображения здесь

Спасибо @CommonsWare.

Я следовал вашим советам, используя отрицательный запас (сверху и снизу), и он работает.

Для этого я просто обновляю AutoFitTextureView проект GoogeSamples android-Camera2Basic следующим образом:

 public class AutoFitTextureView extends TextureView { //... private boolean mWithMargin = false; //... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int margin = (height - width) / 2; if(!mWithMargin) { mWithMargin = true; ViewGroup.MarginLayoutParams margins = ViewGroup.MarginLayoutParams.class.cast(getLayoutParams()); margins.topMargin = -margin; margins.bottomMargin = -margin; margins.leftMargin = 0; margins.rightMargin = 0; setLayoutParams(margins); } if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension(width, height); } else { if (width < height) { setMeasuredDimension(width, width * mRatioHeight / mRatioWidth); } else { setMeasuredDimension(height * mRatioWidth / mRatioHeight, height); } } } } 

Введите описание изображения здесь

Создайте собственный вид текстуры следующим образом:

 public class AutoFitTextureView extends TextureView { private int mCameraWidth = 0; private int mCameraHeight = 0; private boolean mSquarePreview = false; public AutoFitTextureView(Context context) { this(context, null); } public AutoFitTextureView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setAspectRatio(int width, int height, boolean squarePreview) { if (width < 0 || height < 0) { throw new IllegalArgumentException("Size cannot be negative."); } mCameraWidth = width; mCameraHeight = height; mSquarePreview = squarePreview; requestLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mCameraWidth || 0 == mCameraHeight) { setMeasuredDimension(width, height); } else { /** * Vertical orientation */ if (width < height) { if (mSquarePreview) { setTransform(squareTransform(width, height)); setMeasuredDimension(width, width); } else { setMeasuredDimension(width, width * mCameraHeight / mCameraWidth); } } /** * Horizontal orientation */ else { if (mSquarePreview) { setTransform(squareTransform(width, height)); setMeasuredDimension(height, height); } else { setMeasuredDimension(height * mCameraWidth / mCameraHeight, height); } } } } private Matrix setupTransform(int sw, int sh, int dw, int dh) { Matrix matrix = new Matrix(); RectF src = new RectF(0, 0, sw, sh); RectF dst = new RectF(0, 0, dw, dh); RectF screen = new RectF(0, 0, dw, dh); matrix.postRotate(-90, screen.centerX(), screen.centerY()); matrix.mapRect(dst); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); matrix.mapRect(src); matrix.setRectToRect(screen, src, Matrix.ScaleToFit.FILL); matrix.postRotate(-90, screen.centerX(), screen.centerY()); return matrix; } private Matrix squareTransform(int viewWidth, int viewHeight) { Matrix matrix = new Matrix(); if (viewWidth < viewHeight) { MyLogger.log(AutoFitTextureView.class, "Horizontal"); matrix.setScale(1, (float) mCameraHeight / (float) mCameraWidth, viewWidth / 2, viewHeight / 2); } else { MyLogger.log(AutoFitTextureView.class, "Vertical"); matrix.setScale((float) mCameraHeight / (float) mCameraWidth, 1, viewWidth / 2, viewHeight / 2); } return matrix; } } 

И вызовите setAspectRatio для вашего вида текстуры в действии / фрагменте.

 if (mVideoSize.width > mVideoSize.height) { mTextureView.setAspectRatio(mVideoSize.height, mVideoSize.width, true); } else { mTextureView.setAspectRatio(mVideoSize.width, mVideoSize.height, true); } mCamera.setPreviewTexture(mTextureView.getSurfaceTexture()); mCamera.startPreview();