我有一个纹理视图,显示来自相机的视频。纹理视图受右侧带有按钮的固定宽度框架布局的约束。它的底部受到另一个框架布局的限制,该框架布局具有固定的高度,并且宽度应从屏幕的左边缘到主框架布局的左边缘。因此纹理视图的纵横比应该根据设备的屏幕纵横比而变化。
视频预览本身也可以更改宽高比,因为视频大小是用户可选择的。例如,在我的手机上,有 4:3、16:9 和 2:1 视频尺寸选项。所需的行为是视频预览始终适合纹理视图,无需裁剪,也无需拉伸。因此,在大多数情况下,这意味着视频两侧或顶部和底部有黑条。当然,除非纹理视图和视频预览的长宽比恰好相同。
这是我的 XML:(我的应用程序仅是横向的)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.android.camera2video.AutoFitTextureView
android:id="@+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/longTexture"
android:layout_alignLeft="@id/longTexture"
android:layout_alignRight="@id/longTexture"
android:layout_alignTop="@id/mainPanel"
/>
<FrameLayout
android:id="@+id/longTexture"
android:layout_width="match_parent"
android:layout_height="75dp"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/mainPanel"
android:background="#0088FF"
/>
<FrameLayout
android:id="@+id/mainPanel"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:background="#222222"
android:orientation="horizontal">
(Button and spinners here)
</FrameLayout>
</RelativeLayout>
但目前,视频预览似乎总是缩放以适应整个纹理;它没有被拉伸,这很好,但它被裁剪并且不能反映视频的实际宽高比。
顺便说一句,我的应用程序只是对这个旧示例代码的修改:https://github.com/googlearchive/android-Camera2Video。我对其进行了修改,让用户选择视频的分辨率、帧速率和曝光设置。
好吧,我解决了我的问题,我不太确定为什么会这样,但这就是我所做的:
我开始的代码中已经有一个configureTransform函数了:
private void configureTransform(int viewWidth, int viewHeight) {
Activity activity = getActivity();
if (null == mTextureView || null == mPreviewSize || null == activity) {
return;
}
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
}
mTextureView.setTransform(matrix);
}
我所做的只是改变线路
float scale = Math.max(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
到
float scale = Math.min(
(float) viewHeight / mPreviewSize.getHeight(),
(float) viewWidth / mPreviewSize.getWidth());
在用户选择分辨率(以及宽高比)的微调器中,我现在有了线条
mPreviewSize = currentResolution;
configureTransform(mTextureView.getWidth(),mTextureView.getHeight());
startPreview();
我现在确实在纹理视图中获得了视频预览信箱本身所需的行为。