我已经在我的应用中实现了camera2,它正在使用Nexus 6P和Nexus 5.现在我试图在其他设备上测试它,而我试过的第一个就立即失败了。这是我在运行Lollipop的HTC M7上遇到的错误:
TextureView
在这种情况下我应该怎么做?我已经尝试计算最接近TextureView
(即1280x720)的分辨率并相应地调整SurfaceView
的大小,但这看起来并不是特别好 - 太多未使用的空间... Didn& #39; t使用旧相机和TextureView
编辑:
问题似乎在我的 TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
startLollipopPreview(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
int width, int height) {
configureTransform(width,height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
private void startLollipopPreview(int width, int height) {
CameraProxy camera = getCurrentCamera();
try {
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
mPreviewSize = camera
.getOptimalPreviewSize((Activity) mContext,
camera.getSupportedPreviewSizes(
width, height), (double) width / height);
mPreviewTexture.setAspectRatio(mPreviewSize.width, mPreviewSize.height);
mPreviewTexture.getSurfaceTexture().setDefaultBufferSize(mPreviewSize.width,
mPreviewSize.height);
configureTransform(mPreviewSize.width, mPreviewSize.height);
camera.setStateAndHandler(getCameraStateCallback(), mBackgroundHandler);
camera.open();
} catch (CameraHardwareException e) {
Log.e(TAG, ".surfaceCreated() - Error opening camera", e);
((Activity) mContext).finish();
} catch (InterruptedException e) {
Log.e(TAG, ".surfaceCreated() - InterruptedException opening camera", e);
}
}
内。这是我的代码:
在控制器里面我有:
configureTransform()
TextureView
看起来与Camera2谷歌样本完全一样,所以我不认为问题在那里。
在 public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
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 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
params.gravity = Gravity.CENTER_VERTICAL;
setLayoutParams(params);
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}
}
内我有以下内容:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function() {
checkbox2radio('.checkbox');
checkbox2radio('.hamlet');
function checkbox2radio(selector) {
$(selector).on('change', function(e) {
var checked = this.checked;
var index = $(selector).index(this);
if (checked) {
$(selector).each(function(i) {
if(i == index) {
}
else {
$(selector).eq(i).removeAttr('checked');
}
});
}
});
}
})
</script>
<input type="checkbox" class="checkbox"> Foo<br>
<input type="checkbox" class="checkbox"> Bar<br>
<input type="checkbox" class="checkbox"> Hello<br>
<input type="checkbox" class="checkbox"> World<br>
<hr>
<input type="checkbox" class="hamlet"> to<br>
<input type="checkbox" class="hamlet"> be<br>
<input type="checkbox" class="hamlet"> or<br>
<input type="checkbox" class="hamlet"> not<br>
<input type="checkbox" class="hamlet"> to<br>
<input type="checkbox" class="hamlet"> be<br>
答案 0 :(得分:1)
我认为您需要将缓冲区大小设置为支持的预览大小:
textureView.getSurfaceTexture().setDefaultBufferSize(1280,720);
然后您可以缩放TextureView以使其适合您的屏幕,即使预览尺寸较小。 Camera2Video示例有一个例子。具体来看Camera2VideoFragment中的configureTransform
:
/**
* Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
* This method should not to be called until the camera preview size is determined in
* openCamera, or until the size of `mTextureView` is fixed.
*
* @param viewWidth The width of `mTextureView`
* @param viewHeight The height of `mTextureView`
*/
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);
}
答案 1 :(得分:0)
您遇到的问题会根据您测试应用的模拟器/设备而发生变化。
当屏幕尺寸与MediaRecorder设置的设备兼容尺寸不匹配时会发生此错误。
当相机打开(openCamera(int w, int h)
方法)时,它使用chooseOptimalSize(.... .....)
方法获取支持的分辨率的大小。但在此之前,它会设置videoSize()
。
尝试使用Logcat获取支持的大小,并根据设置mMediaRecorder.setVideoSize(w,h);