Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
246 views
in Technique[技术] by (71.8m points)

java - Camera2: Make SurfaceView aspect fit to fill (scaleType CENTER_CROP)

I've been following the Camera2 example (android/camera-samples/Camera2Video) to create an abstraction over the Camera2 library. The idea of my abstraction is to give the user the ability to use a Camera view from React Native, so it's just a <Camera> view which can be whatever size/aspect ratio.

While this works out of the box on iOS, I can't seem to get the preview on Android to display "what the camera sees" in the correct aspect ratio.

The official example from Android works like this:

  • They create a custom SurfaceView extension that should automatically fit to the correct aspect ratio (see: AutoFitSurfaceView)
  • They use that AutoFitSurfaceView in their layout
  • They add a listener to the AutoFitSurfaceView's Surface to find out when it has been created (source)
  • Once the Surface has been created, they call getPreviewOutputSize(...) to get the best matching camera preview size (e.g. so you don't stream 4k for a 1080p screen, that's wasted pixels)
  • Then they pass the best matching camera preview size to the AutoFitSurfaceView::setAspectRatio(...) function
  • By knowing the desired aspect ratio, the AutoFitSurfaceView should then automatically perform a center-crop transform in it's onMeasure override

If you read the source code of their getPreviewOutputSize(...) function, you might notice that this uses a Display to find the best matching preview size. If I understood the code correctly, this would only work if the camera preview (AutoFitSurfaceView) is exactly the same size as the device's screen. This is poorly designed, as there are lots of cases where that simply isn't true. In my case, the Camera has a bit of a bottom spacing/margin, so it doesn't fill the screen and therefore has weird resolutions (1080x1585 on a 1080x1920 screen)

With that long introduction, here comes my question: How do I actually perform a correct center crop transform (aka scaleType = CENTER_CROP) on my SurfaceView? I've tried the following:

  • Set the size of my SurfaceView using SurfaceHolder::setFixedSize(...), but that didn't change anything at all
  • Remove their getPreviewOutputSize(...) stuff and simply use the highest resolution available
  • Use the Android View properties scaleX and scaleY to scale the view by the aspect-ratio difference of the view <-> camera input scaler size (this somewhat worked, but is giving me errors if I try to use high-speed capture: Surface size 1080x1585 is not part of the high speed supported size list [1280x720, 1920x1080])

Any help appreciated!

question from:https://stackoverflow.com/questions/65682233/camera2-make-surfaceview-aspect-fit-to-fill-scaletype-center-crop

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...