I come to you because my custom camera has a problem : the image is stretched. In portrait orientation camera has vertical elongated/stretched. In landscape orientation camera has horizontal elongated/stretched.
Please,help me.
Here is code of my camera:
public class CustomCamera extends Activity {
SurfaceView sv;
SurfaceHolder holder;
HolderCallback holderCallback;
static Camera camera = null;
private boolean hasCamera = false;
Button shotButton;
int CAMERA_ID = 0;
final boolean FULL_SCREEN = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.custom_camera_activity2);
shotButton = (Button) findViewById(R.id.btnTakePicture);
shotButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
camera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
Intent intent = new Intent();
intent.putExtra("data", data);
setResult(RESULT_OK, intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
} catch (NullPointerException ex) {
ex.printStackTrace();
finish();
}
}
});
sv = (SurfaceView) findViewById(R.id.surfaceView);
holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holderCallback = new HolderCallback();
int numCameras = Camera.getNumberOfCameras();
if (numCameras > 0) {
switch (numCameras) {
case 1:
CAMERA_ID = 0;
break;
case 2:
CAMERA_ID = 1;
break;
}
hasCamera = true;
} else {
hasCamera = false;
}
holder.addCallback(holderCallback);
}
@Override
protected void onResume() {
super.onResume();
if (hasCamera) {
try {
camera = Camera.open(CAMERA_ID);
setPreviewSize(FULL_SCREEN);
} catch (Exception e) {
e.printStackTrace();
Log.d(Constant.DEBUG_TAG, "Failed to access to camera");
}
} else {
Toast.makeText(this, "The device has no camera", Toast.LENGTH_SHORT).show();
Log.d(Constant.DEBUG_TAG, "The device has no camera");
}
}
@Override
protected void onPause() {
super.onPause();
if (camera != null) {
camera.stopPreview();
camera.release();
}
camera = null;
}
class HolderCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (NullPointerException ex) {
ex.printStackTrace();
Log.d(Constant.DEBUG_TAG, "Failed to access to camera");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
try {
camera.stopPreview();
setCameraDisplayOrientation(CAMERA_ID);
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
void setPreviewSize(boolean fullScreen) {
Display display = getWindowManager().getDefaultDisplay();
boolean widthIsMax = display.getWidth() > display.getHeight();
Size size = camera.getParameters().getPreviewSize();
RectF rectDisplay = new RectF();
RectF rectPreview = new RectF();
rectDisplay.set(0, 0, display.getWidth(), display.getHeight());
if (widthIsMax) {
rectPreview.set(0, 0, size.width, size.height);
} else {
rectPreview.set(0, 0, size.height, size.width);
}
Matrix matrix = new Matrix();
if (!fullScreen) {
matrix.setRectToRect(rectPreview, rectDisplay,
Matrix.ScaleToFit.START);
} else {
matrix.setRectToRect(rectDisplay, rectPreview,
Matrix.ScaleToFit.START);
matrix.invert(matrix);
}
matrix.mapRect(rectPreview);
sv.getLayoutParams().height = (int) (rectPreview.bottom);
sv.getLayoutParams().width = (int) (rectPreview.right);
}
void setCameraDisplayOrientation(int cameraId) {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result = 0;
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
result = ((360 - degrees) + info.orientation);
} else
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = ((360 - degrees) - info.orientation);
result += 360;
}
result = result % 360;
camera.setDisplayOrientation(result);
Camera.Parameters parameters = camera.getParameters();
int rotate = (degrees + 270) % 360;
parameters.setRotation(rotate);
camera.setParameters(parameters);
}
}
Here is my layout:
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cameraLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
</SurfaceView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnTakePicture"
android:layout_alignBottom="@+id/surfaceView"
android:layout_centerHorizontal="true"
android:text="@string/take_picture" />
</RelativeLayout>