尺寸为1920x1080的Android camera2表面无效

时间:2015-12-17 14:21:40

标签: android camera2

我已经在我的应用中实现了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>

2 个答案:

答案 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);