Hi I am using Camera 2 API in Android for image capture of ID cards, In certain Android version likes 8.1.0 and 9.o the camera view is stretched and items looks longer and slimmer then they should be.
I tried to add padding top bottom of 70dp to root_view layout, that kind of makes it better, but I am sure that is not a correct way.
Can you suggest on what I should be doing please.
Original image using camera
Screenshot of the image through the app using camera 2 api
Here is my XML file in which I am displaying the camera.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:clickable="true">
<TextureView
android:id="@+id/texture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_toolbar_height"
android:paddingTop="24dp"
android:background="#99000000">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/take_photo"
android:gravity="center"
android:layout_gravity="center_vertical"
style="@style/ScreenTitleStyle"/>
</android.support.v7.widget.Toolbar>
<View
android:id="@+id/photo_frame"
android:layout_width="match_parent"
android:layout_height="212dp"
android:background="@drawable/bg_photo_frame"
android:layout_centerInParent="true"
android:layout_margin="@dimen/double_padding"
android:visibility="visible"/>
<RelativeLayout
android:id="@+id/take_picture_panel"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_alignParentBottom="true"
android:background="#99000000">
<TextView
android:id="@+id/take_photo_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#ffffff"
android:letterSpacing="-0.02"
android:lineSpacingExtra="9sp"
android:layout_centerHorizontal="true"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_marginTop="14dp"
style="@style/OpenSansMedium"/>
<Button
android:id="@+id/take_picture_button"
android:layout_gravity="center_horizontal|bottom"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/button_capture"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:enabled="true"
android:layout_marginBottom="12dp"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/approve_picture_panel"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_alignParentBottom="true"
android:background="#99000000"
android:visibility="gone">
<TextView
android:id="@+id/check_photo_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#ffffff"
android:letterSpacing="-0.02"
android:lineSpacingExtra="9sp"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
style="@style/OpenSansMedium"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="21dp">
<Button
android:id="@+id/retake_picture"
android:layout_width="0dp"
android:layout_height="46dp"
android:layout_weight="3"
android:background="@drawable/bg_login_button"
android:enabled="true"
android:layout_marginEnd="6dp"
android:text="@string/retake_button"
style="@style/LoginButtonStyle"
/>
<Button
android:id="@+id/use_picture"
android:layout_width="0dp"
android:layout_height="46dp"
android:layout_weight="5"
android:layout_marginStart="6dp"
android:background="@drawable/bg_login_button"
android:backgroundTint="@color/blueyPurple"
android:enabled="true"
android:textColor="@android:color/white"
android:text="@string/use_button"
style="@style/LoginButtonStyle"
/>
</LinearLayout>
</RelativeLayout>
<FrameLayout
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="@color/transparentWhite"
android:visibility="gone">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true" />
</FrameLayout>
</RelativeLayout>
Here is my .java file which handles the camera2
onresume -
textureView.setSurfaceTextureListener(textureListener);
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//open your camera here
textureViewWidth = width;
textureViewHeight = height;
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Transform you image captured size according to the surface width and height
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private void openCamera() {
Activity activity = getActivity();
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "is camera open");
try {
cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assert map != null;
imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
// Add permission for camera and let user grant the permission
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
return;
}
manager.openCamera(cameraId, stateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
//This is called when the camera is open
Log.e(TAG, "onOpened");
cameraDevice = camera;
createCameraPreview();
}
@Override
public void onDisconnected(CameraDevice camera) {
cameraDevice.close();
}
@Override
public void onError(CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// Auto focus should be continuous for camera preview.
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
Log.e(TAG, "createCaptureSession - onConfigured");
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
//Toast.makeText(TakePhotoFragmentCamera2.this, "Configuration change", Toast.LENGTH_SHORT).show();
Log.e(TAG, "createCaptureSession - onConfigureFailed");
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void updatePreview() {
if(null == cameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
//captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
//captureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}