I have searched about fitting camera preview and surface view but I couldn't find about not stretching image while saving it in android studio.
The camera works well on showing on the surface view of the devices. The ratios of the supported screen sizes and surface view are ok.
The problem is that after capturing the image it takes more from all sides of the surface view of the screen. It just does not take the view that is shown on the surface view but more in all sides of the devices while saving the image.
The problem is only solved when height of the surface view and supported screen sizes are equal. Such as: Supported size is: 1280/720 Surface view is: 405/720 But this leads to a problem which limits the height and width of the surface view. I want height of surface view to be longer and width to be match parent.
So, the problem is not solved without having the heights equal. I want height of the surface view to be longer and width to be match parent.
Can anyone help me with this, Thanks everyone,
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private Context mContext;
private SurfaceHolder mHolder;
private Camera mCamera;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
public int measurewidth, measureheigh;
public CameraPreview(Context context, Camera camera) {
super(context);
mContext = context;
mCamera = camera;
// supported preview sizes
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
for(Camera.Size str: mSupportedPreviewSizes)
Log.e(TAG, str.width + "/" + str.height);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// empty. surfaceChanged will take care of stuff
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged => w=" + w + ", h=" + h);
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or reformatting changes here
// start preview with new settings
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width ,mPreviewSize.height); //B
// parameters.setPreviewSize(1280,720 );
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
Log.e(TAG, "REAL SCREEN SIZE => w=" + width + ", h=" + height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
Log.e(TAG, "MPREVIEW SIZE OPTIMAL => w=" + mPreviewSize.width + ", h=" + mPreviewSize.height);
float ratio;
if(mPreviewSize.height >= mPreviewSize.width)
ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
else
ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
Log.e(TAG, "Ration => R=" + ratio);
// One of these methods should be used, second method squishes preview slightly
//setMeasuredDimension(1080, 1200);
//setMeasuredDimension(mPreviewSize.height, mPreviewSize.width); //B
setMeasuredDimension(width, (int)(width*ratio)); //B
// setMeasuredDimension(720, 1280);
// setMeasuredDimension((int) (width ), height);
measurewidth = width ; // this is for bitmap width
measureheigh = (int)(width*ratio); // this is for bitmap height
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { // long screen
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.width - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.width - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.width - targetHeight) < minDiff) {// size.height was changed with size.width
optimalSize = size;
minDiff = Math.abs(size.width - targetHeight); // size.height was changed with size.width
}
}
}
return optimalSize;
}
}