I have an Android application that needs to fullscreen a camera preview regardless of the preview size given by getSupportedPreviewSizes()
without distortion. I expect this to crop the preview by some amount in either the height or width, but this does not concern me. The reason I seek to do this is because certain android cameras (e.g. Samsung Galaxy SII front facing camera) do not return any previews with the same aspect ratio as the display, and therefore need to be stretched and clipped.
Is it possible to fully grow the camera preview to a view larger than the display size? It is possible to grow the SurfaceView larger than the preview pixel dimensions returned by simply setting the surface view's layout params to match_parent, but this results in distortion in some direction and only is possible up until the preview fills the display. This seems to indicate that previewing outside of the display is impossible, and the hardware (or OS) limits such behavior.
There is another question on the topic, but that question claims it is not possible to create a SurfaceView greater than the screen dimensions, which is false, as I have found with logging. However, what seems to be the case is that camera preview however cannot grow to the full size of an enormous SurfaceView.
My Attempt:
I have a relative layout, within it a FrameLayout, and within that I create a SurfaceView. The width of the entire relative layout is set below at 635dp, which is ~double the device's screen size. The FrameLayout matches this sizing and so does the SurfaceView (added programmatically later)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/camera_activity_layout"
android:layout_width="635dp"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
The following is the code that gets and sets preview size. Here I want to make the camera preview expand to fill the entire FrameLayout (double the screen width). The view shows up and destructs totally normally so I am removing code not related to this particular question because it distracts from the essential question, and my attempt to easily and simply grow the view to some larger-than-display size.
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
...
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
final DisplayMetrics dm = this.getResources().getDisplayMetrics();
//getBestPreviewSize returns the best preview size, don't worry
//but some devices do not return one for all camera matching the aspect ratio
cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels);
if (cameraSize!=null) {
parameters.setPreviewSize(cameraSize.width, cameraSize.height);
mCamera.setParameters(parameters);
}
FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams();
frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT
frameParams.height = LayoutParams.MATCH_PARENT;
this.setLayoutParams(frameParams);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is ");
Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is ");
} catch (Exception e){
}
}
};
I am concerned that the only way to succeed in this endeavor is to somehow render to an openGL surface, but this apparently might be too slow in full color. It is also a pain if the camera preview can simply be stretched and clipped.
Thanks in advance to any attempts at the solution.
See Question&Answers more detail:
os