RedApparat / Fotoapparat

Making Camera for Android more friendly. 📸
Apache License 2.0
3.82k stars 407 forks source link

startPreview and stopPreview should be exposed #381

Open rion18 opened 5 years ago

rion18 commented 5 years ago

Hi, thanks for making this awesome library, it makes working with cameras a lot easier.

What are you trying to achieve or the steps to reproduce?

I have a CameraView on my app. In order to achieve the desired UX, my camera needs to stop preview as soon as I click on my "take picture" button. Using the takePicture method allows for asynchronous processing of the desired bitmap. However, while the bitmap is processing, the camera is still showing a preview (this happens even when debugging the process I use on the bitmap). I cannot use fotoApparat.stop(), since I get a CancellationException when trying to retrieve the image.

The process is as follows:

    photoResult
      .toBitmap()
      .adapt { bitmapFuture -> Single.fromFuture(bitmapFuture) }
      .subscribeOn(Schedulers.io())
      .observeOn(Schedulers.io())
      .map { bitmapPhoto -> CropBitmapPhoto(displayMetrics, bitmapPhoto, cameraView, SELECTED_RATIO) }

// CropBitmapPhoto is a method I made that... well... crops the photo.

How did you initialize FA?

fotoApparat = Fotoapparat(
      context = this,
      view = cameraView,
      logger = logcat(),
      scaleType = ScaleType.CenterCrop,
      lensPosition = back(),
      cameraConfiguration = configuration,
      cameraErrorCallback = { Timber.e(it, "Fatal error on camera") }
    )

What was the result you received?

Logic wise, it all works. I get my bitmap fairly quickly, and I can crop it very fast as well. UX wise: while this processing is happening, the camera is still showing the preview I'm using.

I've tried using this:

1)

    fotoApparat!!.stop()
    photoResult
      .toBitmap()
      .adapt { bitmapFuture -> Single.fromFuture(bitmapFuture) }
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .observeOn(Schedulers.io())
      .map { bitmapPhoto -> CropBitmapPhoto(displayMetrics, bitmapPhoto, cameraView, SELECTED_RATIO) }

And I get a CancellationException.

2)

    photoResult
      .toBitmap()
      .adapt { bitmapFuture -> Single.fromFuture(bitmapFuture) }
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .map { bitmapPhoto ->
        fotoApparat.stop()
        return@map bitmapPhoto
      }
      .observeOn(Schedulers.io())
      .map { bitmapPhoto -> CropBitmapPhoto(displayMetrics, bitmapPhoto, cameraView, SELECTED_RATIO) }

But I still get "some movement" on the preview of the CameraView.

What did you expect?

I expect to have a way to pause/start the preview without calling fotoApparat.stop(), so I can achieve the desired UX and be able to get the image without that nasty CancellationException.

We should be able to use startPreview and stopPreview from the internal CameraDevice class.

Context:

rion18 commented 5 years ago

I can issue a PR if you guys want!