Android:显示相机仍然可以快速捕获到TextureView上吗?

时间:2015-07-29 16:25:09

标签: android image bitmap camera

我正在使用Android Camera2 API拍摄静止图像并将其显示在TextureView上(以便以后进行图像编辑)。

我一直在网上搜索更快的方法:

  1. 将相机图像缓冲区解码为位图
  2. 将位图缩放到屏幕大小并旋转它(因为它旋转90度)
  3. 在纹理视图上显示
  4. 目前我已经为上述方法管理了大约0.8秒的执行时间,但这对于我的特定应用来说太长了。

    我考虑过的一些解决方案是:

    1. 只需预览一帧(按时间顺序,这很快,除了我无法控制自动闪光灯)
    2. 尝试换一个YUV_420_888格式化的图像,然后以某种方式将其变成一个位图(网上有很多东西可能会有所帮助,但我最初的尝试还没有结果)
    3. 只需从相机本身发送质量较差的图像,但从我读过的内容看起来像CaptureRequests中的JPEG_QUALITY参数什么都不做!我也尝试过设置BitmapFactory选项inSampleSize,但速度没有明显改善。
    4. 找到一些方法直接操作图像缓冲区中的jpeg字节数组来转换它然后转换为位图,一次性完成
    5. 以下代码作为参考,采用图像缓冲区,对其进行解码和转换,并将其显示在纹理视图上:

      Canvas canvas = mTextureView.lockCanvas();
      // obtain image bytes (jpeg) from image in camera fragment
      // mFragment.getImage() returns Image object
      ByteBuffer buffer = mFragment.getImage().getPlanes()[0].getBuffer();
      byte[] bytes = new byte[buffer.remaining()];
      buffer.get(bytes);
      // decoding process takes several hundred milliseconds
      Bitmap src = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
      mFragment.getImage().close();
      
      // resize horizontally oriented images
      if (src.getWidth() > src.getHeight()) {
          // transformation matrix that scales and rotates
          Matrix matrix = new Matrix();
          if (CameraLayout.getFace() == CameraCharacteristics.LENS_FACING_FRONT) {
              matrix.setScale(-1, 1);
          }
          matrix.postRotate(90);
          matrix.postScale(((float) canvas.getWidth()) / src.getHeight(),
              ((float) canvas.getHeight()) / src.getWidth());
          // bitmap creation process takes another several hundred millis!
          Bitmap resizedBitmap = Bitmap.createBitmap(
              src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
          canvas.drawBitmap(resizedBitmap, 0, 0, null);
          } else {
              canvas.drawBitmap(src, 0, 0, null);
      }
      // post canvas to texture view
      mTextureView.unlockCanvasAndPost(canvas);
      

      这是我关于堆栈溢出的第一个问题,所以如果我没有完全遵循常见约定,我会道歉。 提前感谢您的任何反馈。

1 个答案:

答案 0 :(得分:0)

如果你所做的只是将它绘制到一个视图中,并且不能保存它,你是否尝试过简单地请求分辨率低于最大值的JPEG,并匹配屏幕尺寸更好?

或者,如果您需要全尺寸图像,JPEG图像通常包含缩略图 - 提取并显示它比处理全分辨率图像要快得多。

就您当前的代码而言,如果可能,您应该避免使用缩放创建第二个Bitmap。当您想要显示图像,然后依靠其内置的缩放比例时,您可以将ImageView放在TextureView的顶部吗? 或者使用Canvas.concat(Matrix)而不是创建中间位图?