API 23 上的 TextureView TranslationX & Y 不是预期的行为
TextureView TranslationX & Y not expected behaviour on API 23
目前我正在制作一个带有 textureview
的相机播放器来渲染我的相机。因为预览可以有任何维度,所以我创建了一些自定义代码来在调用 OnSurfaceTextureUpdated
时更改纹理视图:
void updateTextureMatrix(int width, int height) {
Display display = WindowManager.DefaultDisplay;
var isPortrait = (display.Rotation == SurfaceOrientation.Rotation0 || display.Rotation == SurfaceOrientation.Rotation180);
int previewWidth = orgPreviewWidth;
int previewHeight = orgPreviewHeight;
if(isPortrait) {
previewWidth = orgPreviewHeight;
previewHeight = orgPreviewWidth;
}
// determine which part to crop
float widthRatio = (float)width / previewWidth;
float heightRatio = (float)height / previewHeight;
float scaleX;
float scaleY;
if(widthRatio > heightRatio) {
// height must be cropped
scaleX = 1;
scaleY = widthRatio * ((float)previewHeight / height);
} else {
// width must be cropped
scaleX = heightRatio * ((float)previewWidth / width);
scaleY = 1;
}
Android.Graphics.Matrix matrix = new Android.Graphics.Matrix();
matrix.SetScale(scaleX, scaleY);
_textureView.SetTransform(matrix);
float scaledWidth = width * scaleX;
float scaledHeight = height * scaleY;
float dx = (width - scaledWidth) * 0.5f;
float dy = (height - scaledHeight) * 0.5f;
_textureView.TranslationX = dx;
_textureView.TranslationY = dy;
}
dx
和 dy
的缩放和计算在旧的 android 设备上工作得很好,但我使用的 API 级别 23 的设备抛出意外行为。
galaxy S3正确显示:
但是在 S7 上:
尽管定位正确,phone 还是切掉了很多图像。这让我相信底部部分没有在旧设备上呈现。任何人都可以确认这一点并指出我正确的位置来解决这个问题吗?
经过长时间的测试,我发现问题出在 SetTransform
方法上。我正在使用矩阵设置我的比例,但这以某种方式渲染了我的纹理并忽略了 TranslationX
和 TranslationY
。删除矩阵并将其替换为
float scaledWidth = width * scaleX;
float scaledHeight = height * scaleY;
float dx = (width - scaledWidth) * 0.5f;
float dy = (height - scaledHeight) * 0.5f;
_textureView.ScaleX = scaleX;
_textureView.ScaleY = scaleY;
_textureView.TranslationX = dx;
_textureView.TranslationY = dy;
解决了我在某些 android 设备上渲染错误的问题。
目前我正在制作一个带有 textureview
的相机播放器来渲染我的相机。因为预览可以有任何维度,所以我创建了一些自定义代码来在调用 OnSurfaceTextureUpdated
时更改纹理视图:
void updateTextureMatrix(int width, int height) {
Display display = WindowManager.DefaultDisplay;
var isPortrait = (display.Rotation == SurfaceOrientation.Rotation0 || display.Rotation == SurfaceOrientation.Rotation180);
int previewWidth = orgPreviewWidth;
int previewHeight = orgPreviewHeight;
if(isPortrait) {
previewWidth = orgPreviewHeight;
previewHeight = orgPreviewWidth;
}
// determine which part to crop
float widthRatio = (float)width / previewWidth;
float heightRatio = (float)height / previewHeight;
float scaleX;
float scaleY;
if(widthRatio > heightRatio) {
// height must be cropped
scaleX = 1;
scaleY = widthRatio * ((float)previewHeight / height);
} else {
// width must be cropped
scaleX = heightRatio * ((float)previewWidth / width);
scaleY = 1;
}
Android.Graphics.Matrix matrix = new Android.Graphics.Matrix();
matrix.SetScale(scaleX, scaleY);
_textureView.SetTransform(matrix);
float scaledWidth = width * scaleX;
float scaledHeight = height * scaleY;
float dx = (width - scaledWidth) * 0.5f;
float dy = (height - scaledHeight) * 0.5f;
_textureView.TranslationX = dx;
_textureView.TranslationY = dy;
}
dx
和 dy
的缩放和计算在旧的 android 设备上工作得很好,但我使用的 API 级别 23 的设备抛出意外行为。
galaxy S3正确显示:
但是在 S7 上:
尽管定位正确,phone 还是切掉了很多图像。这让我相信底部部分没有在旧设备上呈现。任何人都可以确认这一点并指出我正确的位置来解决这个问题吗?
经过长时间的测试,我发现问题出在 SetTransform
方法上。我正在使用矩阵设置我的比例,但这以某种方式渲染了我的纹理并忽略了 TranslationX
和 TranslationY
。删除矩阵并将其替换为
float scaledWidth = width * scaleX;
float scaledHeight = height * scaleY;
float dx = (width - scaledWidth) * 0.5f;
float dy = (height - scaledHeight) * 0.5f;
_textureView.ScaleX = scaleX;
_textureView.ScaleY = scaleY;
_textureView.TranslationX = dx;
_textureView.TranslationY = dy;
解决了我在某些 android 设备上渲染错误的问题。