在运行时更改Android Camera 2的Flash设置

时间:2016-02-25 06:56:21

标签: java android mobile android-camera2

基本上,我要做的是通过应用程序中的按钮单击更改CONTROL_AE_MODE。用户可以使用AUTO flash(ON_AUTO_FLASH),如果ON(ON_ALWAYS_FLASH)或OFF(CONTROL_AE_MODE_OFF)则转动。

在此示例中:https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java

第818行,他们设置了一次闪光灯:

private void btnSave_Click(object sender, EventArgs e)
            {
                dgvHead.EndEdit();
                dgvHead.RefreshEdit();
                dgvHead.Refresh();
                dgvHead.Update();
                dgvHead.LostFocus += new EventHandler(dataGridView1_LostFocus);
                //dgvHead.ClearSelection();


            //int id = 0;
            //保存到数据库之前先判断一下主表是否有重复记录
            string fno = txtfNo.Text.Trim();
            string fname = txtPname.Text.Trim();
            int orderqty = Convert.ToInt32(txtOrderQty.Text);
            double orderc = Convert.ToDouble(txtOrderCoefficient.Text);
            Image pic = pbchef.Image;
            //主表的修改
            string sql1 = "select count(1) from desProductAttach where fno='" + fno + "' and fno!='" + args["pNo"].ToString() + "' and fname='" + fname + "' and orderqty=" + orderqty + " and orderCoefficient=" + orderc + "";
            int count = Convert.ToInt32(SqlHelp.GetValue(CommandType.Text, sql1));
            if (count != 0)
            {
                MessageBox.Show("数据库中已经存在重复记录,请修改后重新录入!");
                return;
            }
            string sql2 = @"update desProductAttach set fno='" + fno + "',fname='" + fname + "',orderqty=" + orderqty + ",orderCoefficient=" + orderc + " where id="+id+"";
            SqlHelp.ExecuteNonQuery(CommandType.Text,sql2);

           //子表的更新(通过数据源更新)
            if (ds1.HasChanges())
            {
                SqlCommandBuilder cb = new SqlCommandBuilder(sda1);
                sda1.Update(ds1.Tables[0]);
                ds1.AcceptChanges();
               // dgvHead.Update();
                MessageBox.Show("保存成功");
               // ischange = false;
            }

        }

然后在840行构建CaptureSession。

有没有办法在预览完成后更改CONTROL_AE_MODE?

我尝试过改造会议,这有点奏效:

// Use the same AE and AF modes as the preview.
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setAutoFlash(captureBuilder);

            // Orientation
            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

            CameraCaptureSession.CaptureCallback CaptureCallback
                    = new CameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    showToast("Saved: " + mFile);
                    Log.d(TAG, mFile.toString());
                    unlockFocus();
                }
            };

            mCaptureSession.stopRepeating();
            mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);

出于某种原因,CONTROL_AE_MODE_OFF会将整个预览变为黑色。 我试着在文档中查找更新方法,但却找不到任何东西。

非常感谢任何教程或文档。

3 个答案:

答案 0 :(得分:4)

我不知道为什么你的预览会变黑,但你不需要手动关闭捕获会话。来自.close()方法的文档:

  

直接使用createCaptureSession(List , CameraCaptureSession.StateCallback, Handler)而不关闭是推荐的方法   快速切换到新会话,因为未更改的目标输出可以   可以更有效地重复使用。

因此,您可以重用现有的CaptureRequest.Builder,设置更改的值,构建新的PreviewRequest,并使用此新请求启动新会话,如下所示:

try {
    // Change some capture settings
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
    // Build new request (we can't just edit existing one, as it is immutable)
    mPreviewRequest = mPreviewRequestBuilder.build();
    // Set new repeating request with our changed one
    mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

它会更快(几乎没有任何可见的预览冻结)。

答案 1 :(得分:2)

如@ cyborg86pl所述,在切换闪光模式时,请勿切换CONTROL_AE_MODE。相反,您可以在FLASH_MODE之间切换。这是我的案例的有效示例:

  when (currentFlashState) {
        FlashState.AUTO -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
        }
        FlashState.ON -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
          previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH)
        }
        FlashState.OFF -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
          previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
        }
      }
 previewRequest = previewRequestBuilder.build()
 captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler)

答案 2 :(得分:1)

你想要的是禁用闪光,而不是自动曝光(AE),因此你想使用CONTROL_AE_MODE_ON而不是CONTROL_AE_MODE_OFF

documentation中所述:

  

CONTROL_AE_MODE_ON

     

相机设备的自动曝光程序处于活动状态,没有闪光控制。