Why can I not open camera in Android? - android

I'm a beginner in android and I want to open the camera and capture picture automatically.
My Code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++ ){
Camera.getCameraInfo(camIdx, cameraInfo);
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ){
try {
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
Log.i("Camera failed to open: ", e.getLocalizedMessage());
}
}
}
SurfaceView surface = new SurfaceView(this);
try {
cam.setPreviewDisplay(surface.getHolder());
}catch(IOException e){
e.printStackTrace();
}
}
But when code is run, camera intent does not start and shows me black page,and doesn't take a picture automatically. How can I solve that?thanks.

File cDir = getExternalFilesDir(null);
cDir.mkdir();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
String mPhotoresultingFile = new File(cDir.toString()+ "/image.jpg");
Uri uriSavedImage = Uri.fromFile(mPhotoresultingFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,uriSavedImage);
startActivityForResult(cameraIntent, 1888);
add onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
if (mPhotoresultingFile.exists()) {
Bitmap photo = BitmapFactory.decodeFile(mPhotoresultingFile
.getPath());
ExifInterface exif = new ExifInterface(
mPhotoresultingFile.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
photo = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(),
photo.getHeight(), matrix, true);
//If you want to delete the captured photo from the gallery
mPhotoresultingFile.delete();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
And add Camers Uses Permission in your manifest file.
<uses-permission android:name="android.permission.CAMERA"></uses-permission>

Make sure you have defined the following permission:
<uses-permission android:name="android.permission.CAMERA" />
and also:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
defined in your AndroidManifest.xml

you can try to open back camera by changing your code to, cam = Camera.open( 0 );
Use below complete code for your project, code include pinch zoom camera as well as rotation features !
public class RecordLiveVideo extends Activity implements SurfaceHolder.Callback
{
private Camera camera;
private SurfaceView surfaceView;
Button btn_record, btn_rotate;
TextView tv_timer;
MediaRecorder mediaRecorder;
int temp_for_start_stop_button = 0;
long start_time;
static Boolean has_front_camera;
int current_camera = 0;
int recording_degree;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.recordlivevideo);
InitCamera(0);
btn_record = (Button) findViewById(R.id.btn_record);
tv_timer = (TextView) findViewById(R.id.tv_timer);
tv_timer.setVisibility(View.GONE);
btn_rotate = (Button) findViewById(R.id.btn_rotate);
int n = Camera.getNumberOfCameras();
if (n > 1)
{
has_front_camera = true;
}
else
{
has_front_camera = false;
btn_rotate.setBackground(getResources().getDrawable(R.drawable.rotation_close));
}
btn_rotate.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
if (has_front_camera == true)
{
camera.stopPreview();
camera.release();
camera = null;
if (current_camera == 0)
{
//start front
//recording_degree = 270;
current_camera = 1;
InitCamera(1);
}
else
{
//start back
//recording_degree = degree;
current_camera = 0;
InitCamera(0);
}
}
else
{
Toast.makeText(getApplicationContext(), "Device has not front camera !", Toast.LENGTH_SHORT).show();
}
}
});
btn_record.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if (temp_for_start_stop_button == 0)
{
if (startRecording())
{
tv_timer.setVisibility(View.VISIBLE);
tv_timer.setText("0 : 0");
temp_for_start_stop_button = 1;
btn_record.setBackground(getResources().getDrawable(R.drawable.stop_camera));
start_time = System.currentTimeMillis();
show_current_time();
}
}
else
{
tv_timer.setVisibility(View.GONE);
temp_for_start_stop_button = 0;
btn_record.setBackground(getResources().getDrawable(R.drawable.camera));
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(new File(uniqueOutFile));
mediaScanIntent.setData(contentUri);
RecordLiveVideo.this.sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
}
});
}
void InitCamera(int n)
{
surfaceView = (SurfaceView) findViewById(R.id.preview);
surfaceView.getHolder().addCallback(this);
try
{
camera = Camera.open(n);
Camera.Parameters parametro = camera.getParameters();
parametro.setColorEffect(Camera.Parameters.EFFECT_MONO);
parametro.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
camera.setParameters(parametro);
setCameraDisplayOrientation(RecordLiveVideo.this, n, camera);
camera.setPreviewDisplay(surfaceView.getHolder());
camera.startPreview();
}
catch (final Exception e)
{
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
camera.release();
camera = null;
}
}
void show_current_time()
{
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
long duration = (int) ((System.currentTimeMillis() - start_time) / 1000);
int min = 00;
int sec = 00;
min = (int) duration / 60;
sec = (int) (duration % 60);
//Log.e("MAYUR", "" + min + " : " + sec);
if (temp_for_start_stop_button == 1)
{
tv_timer.setText("" + min + " : " + sec);
show_current_time();
}
}
}, 1000);
}
int degree;
//int result;
public void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera)
{
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.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;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270)
degree = result;
else
degree = result + 180;
}
else
{ // back-facing
result = (info.orientation - degrees + 360) % 360;
degree = result;
}
camera.setDisplayOrientation(result);
}
#Override
protected void onDestroy()
{
super.onDestroy();
if (camera != null)
{
camera.release();
}
}
#Override
protected void onPause()
{
super.onPause();
if (camera != null)
{
try
{
camera.stopPreview();
}
catch (Exception e)
{
// TODO: handle exception
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
camera.setPreviewDisplay(holder);
//camera.startPreview();
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
if (holder.getSurface() == null)
{
// preview surface does not exist
return;
}
if (holder.getSurface() != null)
{
try
{
camera.stopPreview();
}
catch (Exception e)
{
}
try
{
camera.setPreviewDisplay(holder);
camera.startPreview();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
String uniqueOutFile = null;
public boolean startRecording()
{
try
{
if (degree == 90 || degree == 270)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//camera.setDisplayOrientation(degree);
camera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener()
{
#Override
public void onError(MediaRecorder mr, int what, int extra)
{
Log.i("mayur", "Error");
}
});
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
uniqueOutFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoEffect/VideoEffect_Camera_" + System.currentTimeMillis() + ".mp4";
File outFile = new File(uniqueOutFile);
if (outFile.exists())
{
outFile.delete();
}
mediaRecorder.setOutputFile(uniqueOutFile);
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoEncodingBitRate(3000000);
mediaRecorder.setVideoSize(640, 480);
//mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
mediaRecorder.setOrientationHint(degree);
mediaRecorder.prepare();
mediaRecorder.start();
return true;
}
catch (Exception e)
{
camera.lock();
return false;
}
}
private float mDist;
#Override
public boolean onTouchEvent(MotionEvent event)
{
// Get the pointer ID
Camera.Parameters params = camera.getParameters();
int action = event.getAction();
if (event.getPointerCount() > 1)
{
// handle multi-touch events
if (action == MotionEvent.ACTION_POINTER_DOWN)
{
mDist = getFingerSpacing(event);
}
else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported())
{
camera.cancelAutoFocus();
handleZoom(event, params);
}
}
else
{
// handle single touch events
if (action == MotionEvent.ACTION_UP)
{
handleFocus(event, params);
}
}
return true;
}
private void handleZoom(MotionEvent event, Camera.Parameters params)
{
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
float newDist = getFingerSpacing(event);
if (newDist > mDist)
{
//zoom in
if (zoom < maxZoom - 1)
zoom += 2;
}
else if (newDist < mDist)
{
//zoom out
if (zoom > 1)
zoom -= 2;
}
mDist = newDist;
params.setZoom(zoom);
camera.setParameters(params);
}
public void handleFocus(MotionEvent event, Camera.Parameters params)
{
//int pointerId = event.getPointerId(0);
//int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
// float x = event.getX(pointerIndex);
// float y = event.getY(pointerIndex);
List<String> supportedFocusModes = params.getSupportedFocusModes();
if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
{
camera.autoFocus(new Camera.AutoFocusCallback()
{
#Override
public void onAutoFocus(boolean b, Camera camera)
{
// currently set to auto-focus on single touch
}
});
}
}
/** Determine the space between the first two fingers */
private float getFingerSpacing(MotionEvent event)
{
// ...
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
#Override
public void onBackPressed()
{
// TODO Auto-generated method stub
super.onBackPressed();
finish();
}
}
Enjoy !!

Related

How to rotate the captured image using Camera class

I am trying to implement a custom camera by using Camera class and SurfaceView. But the image taken by camera gets rotated. The preview in SurfaceView was also rotating but in the code i have fixed it by using the setCameraDisplayOrientation() method.Below are the images that gets generated in the screen & i took screenshots.
surfaceView: ImageView:
And the code i am using is:
public class CustomCameraActivity extends AppCompatActivity implements PictureCallback, SurfaceHolder.Callback
{
private Camera mCamera;
private ImageView mCameraImage;
private SurfaceView mCameraPreview;
private Button mCaptureImageButton;
private byte[] mCameraData;
private boolean mIsCapturing;
private OnClickListener mCaptureImageButtonClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
App.getInstance().setCapturedPhotoData(null);
captureImage();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_camera);
mImgViewCover = (ImageView) findViewById(R.id.imgVw_customCameraCover);
mCameraImage = (ImageView) findViewById(R.id.camera_image_view);
mCameraImage.setVisibility(View.INVISIBLE);
mCameraPreview = (SurfaceView) findViewById(R.id.preview_view);
final SurfaceHolder surfaceHolder = mCameraPreview.getHolder();
surfaceHolder.addCallback(this);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCaptureImageButton = (Button) findViewById(R.id.capture_image_button);
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
mIsCapturing = true;
}
#Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(mCameraPreview.getHolder());
if (mIsCapturing) {
mCamera.startPreview();
}
} catch (Exception e) {
Toast.makeText(CustomCameraActivity.this, "Unable to open camera.", Toast.LENGTH_LONG)
.show();
}
}
}
#Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
mCameraData = data;
setupImageDisplay();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null)
return;
try { mCamera.stopPreview();
} catch (Exception e) { }
if (mCamera != null) {
try {
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera );
if (mIsCapturing) {
mCamera.startPreview();
}
} catch (Exception e) {
Toast.makeText(CustomCameraActivity.this, "Unable to start camera preview.", Toast.LENGTH_LONG).show();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null)
{ mCamera.stopPreview();
mCamera.release();
mCamera = null;}
}
private void captureImage() {
mCamera.takePicture(null, null, this);
}
private void setupImageCapture() {
mCameraImage.setVisibility(View.INVISIBLE);
mCameraPreview.setVisibility(View.VISIBLE);
mCamera.startPreview();
mCaptureImageButton.setText("capture image");
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
}
private void setupImageDisplay() {
Bitmap bitmap = BitmapFactory.decodeByteArray(mCameraData, 0, mCameraData.length);
mCameraImage.setImageBitmap(bitmap);
mCamera.stopPreview();
mCameraPreview.setVisibility(View.INVISIBLE);
mCameraImage.setVisibility(View.VISIBLE);
if (mCameraData != null) {
Intent intent = new Intent();
intent.putExtra(EXTRA_CAMERA_DATA, mCameraData);
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.5;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public static void setCameraDisplayOrientation(Context context,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = ((Activity)context).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;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
// camera.getParameters().setRotation(result);
}
}
I can rotate the bitmap to 90 before showing in imageview -by using the code:
public static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}
But it shouldn't be the proper way to solve it. So, how do i fix this and show the non-rotated image in imageView?
Use this way to open camera using surface view Java Code
public class CameraOverlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
private File videoPath;
private ImageView imgCapture;
int camBackId;
String strVideoFolderPath;
private ProgressDialog progressDialog;
Camera.Parameters parameters;
public boolean hasFlash;
public boolean camRotation = false;
private RelativeLayout relativeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_overlay);
relativeLayout = findViewById(R.id.control);
camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
hasFlash = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
surfaceView = findViewById(R.id.surface);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle(null);
progressDialog.setCancelable(false);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
strVideoFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
videoPath = new File(Environment.getExternalStorageDirectory() + "/sw/raw");
if (videoPath.exists()) {
if (videoPath.isDirectory()) {
if (videoPath.listFiles().length != 0) {
String[] children = videoPath.list();
for (int i = 0; i < children.length; i++) {
new File(videoPath, children[i]).delete();
}
}
}
}
if (!videoPath.exists()) {
videoPath.mkdirs();
}
imgCapture = findViewById(R.id.img_capture);
imgCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (camera != null) {
if (previewing) {
System.gc();
try {
capturePhoto();
} catch (Exception e) {
Log.v("ERRORR", e.getMessage());
e.printStackTrace();
}
}
}
}
});
}
public void capturePhoto() throws Exception {
camera.takePicture(null, null, myPictureCallback_JPG);
}
#Override
protected void onResume() {
super.onResume();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
}
Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
FileOutputStream outStream = null;
//camera.startPreview();
try {
Date date = new Date();
String filename = "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".jpg";
filename = filename.replace("+", "");
File file = new File(Environment.getExternalStorageDirectory() + "/Switch It");
if (!file.exists())
file.mkdirs();
outStream = new FileOutputStream(file + filename);
outStream.write(arg0);
outStream.close();
Log.v("File_Path", file.getAbsolutePath());
Intent returnIntent = new Intent();
returnIntent.putExtra("img_capture", file.getAbsolutePath() + filename);
setResult(Activity.RESULT_OK, returnIntent);
finish();
} catch (FileNotFoundException e) {
Log.e("ERROR 1", e.getMessage());
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Log.e("ERROR 2", e.getMessage());
} finally {
}
}
};
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
parameters = camera.getParameters();
if (getPackageManager().hasSystemFeature("android.hardware.camera.autofocus")) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
camera.startPreview();
if (hasFlash) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
camera.setParameters(parameters);
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
if (android.os.Build.VERSION.SDK_INT > 7) {
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
camera.setDisplayOrientation(90);
camRotation = true;
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
}
Rotate your imageview on angle whenever your image not rotated as per your requirement You can rotate your ImageView Using this
mImageView.setRotation(yourRequiredAngle)
Hope it helps.

How to get rid of camera freezes (SurfaceView)?

I'm trying to create custom camera using Camera API. I have already looked through a lot of similar questions, but anyway can't get rid from freezes in my Camera Preview. Sometimes preview freezes when activity started, despite of using another thread. But when I try to switch to face camera, preview image Freezes every time. In log i Got only something like this:
I/Choreographer: Skipped 41 frames! The application may be doing too much work on its main thread.
My SurfaceView is placed in Fragment in ViewPager activity if it's matter.
My Custom Camera class methods:
Set Display Orientation:
void setCameraDisplayOrientation(int cameraId) {
int rotation = getActivity().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);
}
Holder Callback class:
class HolderCallback implements SurfaceHolder.Callback {
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (mIsPreviewing) {
camera.stopPreview();
mIsPreviewing = false;
}
if (camera != null) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size bestSize = getBestPreviewSize(width, height, parameters);
if (bestSize != null) {
parameters.setPreviewSize(bestSize.width, bestSize.height);
camera.setParameters(parameters);
Toast.makeText(
getActivity().getApplicationContext(),
"Оптимальный размер: " + String.valueOf(bestSize.width)
+ " : " + String.valueOf(bestSize.height),
Toast.LENGTH_LONG).show();
}
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
mIsPreviewing = true;
// camera.autoFocus(autoFocusCallback);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size bestSize = null;
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
bestSize = sizeList.get(0);
for (int i = 1; i < sizeList.size(); i++) {
if ((sizeList.get(i).width * sizeList.get(i).height) > (bestSize.width * bestSize.height)) {
bestSize = sizeList.get(i);
}
}
return bestSize;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
Camera Handler Thread:
private CameraHandlerThread mThread = null;
private static class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
}
void openCamera() {
mHandler.post(new Runnable() {
#Override
public void run() {
camera = Camera.open(CAMERA_ID);
//set camera to continually auto-focus
Camera.Parameters params = camera.getParameters();
//*EDIT*//params.setFocusMode("continuous-picture");
//It is better to use defined constraints as opposed to String, thanks to AbdelHady
// params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
// camera.setParameters(params);
//STEP #1: Get rotation degrees
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break; //Natural orientation
case Surface.ROTATION_90: degrees = 90; break; //Landscape left
case Surface.ROTATION_180: degrees = 180; break;//Upside down
case Surface.ROTATION_270: degrees = 270; break;//Landscape right
}
int rotate = (info.orientation - degrees + 360) % 360;
//STEP #2: Set the 'rotation' parameter
params.setRotation(rotate);
camera.setParameters(params);
notifyCameraOpened();
camera.startPreview();
}
});
try {
wait();
}
catch (InterruptedException e) {
Log.d(TAG, "openCamera: Cannot open Camera");
}
}
}
Opening camera:
private void newOpenCamera() {
mThread = new CameraHandlerThread();
synchronized (mThread) {
mThread.openCamera();
}
}
Fragment methods:
#Override
public void onResume() {
super.onResume();
newOpenCamera();
setCameraDisplayOrientation(CAMERA_ID);
}
#Override
public void onPause() {
super.onPause();
if (camera != null)
camera.release();
camera = null;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
sv = (SurfaceView) getActivity().findViewById(R.id.surfaceView);
makePhotoBtn = (ImageView) getActivity().findViewById(R.id.makephotoBtn);
switchCameraBtn = (ImageView) getActivity().findViewById(R.id.switchCameraBtn);
holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holderCallback = new HolderCallback();
holder.addCallback(holderCallback);
rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
makePhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
new SaveBitmap().execute(toObjects(data));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
switchCameraBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
swapCamera();
}
});
}
And Swap Camera Method:
private void swapCamera() {
if (camera != null) {
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
holder.removeCallback(holderCallback);
holder = null;
sv = null;
sv = (SurfaceView) getActivity().findViewById(R.id.surfaceView);
}
//swap the id of the camera to be used
if (CAMERA_ID == Camera.CameraInfo.CAMERA_FACING_FRONT) {
CAMERA_ID = 0;
} else {
CAMERA_ID = 1;
}
newOpenCamera();
}
What can I do to get rid of freezes in this case? Appreciate any help!

How resize the image bitmap with the custom layout height and width

I am using the fallowing solution to resize the bitmap. But it results portion of the image is lost.
Here is is my code.
BitmapFactory.Options bmFactoryOptions = new BitmapFactory.Options();
bmFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmFactoryOptions.inMutable = true;
bmFactoryOptions.inSampleSize = 2;
Bitmap originalCameraBitmap = BitmapFactory.decodeByteArray(pData, 0, pData.length, bmFactoryOptions);
rotatedBitmap = getResizedBitmap(originalCameraBitmap, cameraPreviewLayout.getHeight(), cameraPreviewLayout.getWidth() - preSizePriviewHight(), (int) rotationDegrees);
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight, int angle) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
DeliverItApplication.getInstance().setImageCaptured(true);
return resizedBitmap;
}
And here is the image height and width : Preview surface size:352:288 Before resized bitmap width : 320 Height : 240 CameraPreviewLayout width : 1080 Height : 1362 Resized bitmap width : 1022 Height : 1307
Your java code is right but you haven't care about Aspect Ratio of Image thats whys your Image Portion is cutting.
Original Image Height and Width :
Height = 352;
Width = 288;
Aspect Ratio = h/w; => Ratio = 1.2;
and you taken new width and height :
newHeight = 320;
newWidth = 240;
But if we take Image Height as 320 then according Image Aspect Ratio Its Width becomes :
calculated width = newHeight /Ratio; => 320/1.2= 266.66= 267;
calculated width = 267;
difference of portion cutting is = calculated width -newWidth;
= 267 -240 ;
= 27 ;
So you need to take height and width for new bitmap.
newHeight = 320;
newWidth = 267 ;
public class MarkableImageCaptureActivity extends Activity implements OnClickListener {
private static Logger logger = LoggerFactory.getLogger(MarkableImageCaptureActivity.class);
#InjectView(R.id.top_menu_bar)
private LinearLayout topMenuLayout;
#InjectView(R.id.top_menu_title)
private TextView topMenuTitleTV;
#InjectView(R.id.image_desc_edittext)
private EditText imageDescEditText;
#InjectView(R.id.camerapreview_layout)
private FrameLayout cameraPreviewLayout;
#InjectView(R.id.btn_camera_capture)
private Button captureBtn;
#InjectView(R.id.btn_camera_save)
private Button saveBtn;
#InjectView(R.id.btn_camera_cancel)
private Button cancelBtn;
#InjectView(R.id.edit_captured_image_layout)
private RelativeLayout editCapturedImageLayout;
#InjectView(R.id.edit_captured_image)
private ImageView editCapturedImage;
#InjectView(R.id.color_container_layout)
private LinearLayout colorContainerLayout;
#InjectView(R.id.btn_markable_red)
private Button btnMarkableRed;
#InjectView(R.id.btn_markable_blue)
private Button btnMarkableBlue;
#InjectView(R.id.btn_markable_green)
private Button btnMarkableGreen;
#InjectView(R.id.btn_markable_white)
private Button btnMarkableWhite;
#InjectView(R.id.btn_markable_black)
private Button btnMarkableBlack;
#InjectView(R.id.btn_undo)
private TextView capturedImageUndo;
private MarkableImageView editableCapturedImageview;
#InjectView(R.id.flashSwitch)
private ToggleButton flashToggle;
private static final int DIALOG_CAPTURE_EXCEPTION = 2101;
private static final int DIALOG_CAPTURING_EXCEPTION = 2102;
private static final int DIALOG_SAVE_EXCEPTION = 0;
private String imageFileName = null;
private File imageFile = null;
private Stop targetStop = null;
private int stopId = DIntent.VALUE_INVALID_ID;
private float rotationDegrees = 0;
private Camera camera = null;
private CameraPreview cameraPreview;
private Bitmap rotatedBitmap;
private static final int PRIMARY_CAMERA_ID = 0;
private boolean imageCaptured = false;
private boolean inPreview = false;
private boolean isFlashSupports;
private boolean isCapturing = false;
private boolean isFlashOn;
private boolean isDocNameEditable;
private String imageDesc = "";
private Handler focusHandler = null;
private int captureType;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_start_camera_for_photo_capture);
setupTopMenuBar(topMenuLayout, null, getString(R.string.menuitem_back), getString(R.string.menuitem_done), true, true, new ImageCaptureTopMenuListener());
focusHandler = new Handler();
editableCapturedImageview = (MarkableImageView) findViewById(R.id.editable_captured_imageview);
Bundle intentBundle = getIntent().getExtras();
isDocNameEditable = getIntent().getBooleanExtra(DIntent.EXTRA_OBJECT_TYPE_DOCUMENT_EDITABLE, false);
imageDesc = getIntent().getStringExtra(DIntent.EXTRA_OBJECT_TYPE_DOCUMENT_NAME);
if (savedInstanceState != null) {
stopId = savedInstanceState.getInt(DIntent.EXTRA_STOP_ID);
imageDesc = savedInstanceState.getString(DIntent.EXTRA_IMAGE_DESC);
imageCaptured = savedInstanceState.getBoolean(DIntent.EXTRA_IS_IMAGE_CAPTURED);
inPreview = savedInstanceState.getBoolean(DIntent.EXTRA_IN_PREVIEW);
isFlashOn=savedInstanceState.getBoolean(DIntent.FLASH_MODE_ON);
if (imageCaptured) {
rotatedBitmap = savedInstanceState.getParcelable(DIntent.EXTRA_IMAGE_BITMAP);
}
}
captureType = intentBundle.getInt(DIntent.EXTRA_TYPE_CAPTURE);
if (captureType == DIntent.EXTRA_TYPE_IMAGE_CAPTURE) {
stopId = intentBundle.getInt(DIntent.EXTRA_STOP_ID);
try {
targetStop = getDbHelper().getStopDao().queryForId(stopId);
} catch (SQLException e) {
logger.error("Exception finding stop by Id!!", e);
}
}
isFlashSupports = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (isFlashSupports) {
flashToggle.setVisibility(View.VISIBLE);
flashToggle.setOnClickListener(this);
} else {
flashToggle.setVisibility(View.GONE);
}
captureBtn.setOnClickListener(this);
saveBtn.setOnClickListener(this);
cancelBtn.setOnClickListener(this);
imageDescEditText.setText(imageDesc);
if (AndroidUtility.isValidTrimmedString(imageDesc)) {
if (!isDocNameEditable) {
imageDescEditText.setEnabled(false);
}
} else {
imageDescEditText.setEnabled(true);
}
editCapturedImage.setOnClickListener(this);
btnMarkableWhite.setOnClickListener(this);
btnMarkableRed.setOnClickListener(this);
btnMarkableBlue.setOnClickListener(this);
btnMarkableGreen.setOnClickListener(this);
btnMarkableBlack.setOnClickListener(this);
capturedImageUndo.setOnClickListener(this);
}
#Override
protected void onStart() {
super.onStart();
logger.info("onStart:imageCaptured" + imageCaptured);
boolean isImageCaptured = DeliverItApplication.getInstance().isImageCaptured();
if (!isImageCaptured) {
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
}
}
private void activateCapturedImageView(Bitmap rotatedBitmap) {
cameraPreviewLayout.setVisibility(View.GONE);
editableCapturedImageview.setCapturedBitmap(rotatedBitmap);
editableCapturedImageview.setVisibility(View.VISIBLE);
editCapturedImageLayout.setVisibility(View.VISIBLE);
captureBtn.setVisibility(View.GONE);
saveBtn.setVisibility(View.VISIBLE);
saveBtn.requestFocus();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) editableCapturedImageview.getLayoutParams();
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
layoutParams.width = rotatedBitmap.getWidth();
layoutParams.height = rotatedBitmap.getHeight();
editableCapturedImageview.setLayoutParams(layoutParams);
logger.info("Inside activateCapturedImageView");
releaseCamera();
}
private void activatePreviewLayout() {
logger.info("Insie activatePreviewLayout");
cameraPreviewLayout.setVisibility(View.VISIBLE);
editableCapturedImageview.setVisibility(View.GONE);
editCapturedImageLayout.setVisibility(View.GONE);
captureBtn.setVisibility(View.VISIBLE);
captureBtn.requestFocus();
saveBtn.setVisibility(View.GONE);
}
#Override
protected void onResume() {
super.onResume();
logger.info("onResume");
if (rotatedBitmap == null || inPreview) {
activateCameraPreview();
}
}
public void activateCameraPreview() {
logger.info("activateCameraPreview");
camera = getCameraInstance(camera);
if (camera != null) {
cameraPreview = new CameraPreview(this, camera);
rotationDegrees = getCameraDisplayOrientation(this, PRIMARY_CAMERA_ID);
camera.setDisplayOrientation((int) rotationDegrees);
cameraPreviewLayout.addView(cameraPreview);
inPreview = true;
isCapturing = false;
Camera.Parameters params = camera.getParameters();
if (isFlashSupported(params)) {
logger.info("activateCameraPreview: Flash Mode:"+ isFlashOn);
if (isFlashOn) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
} else {
flashToggle.setVisibility(View.GONE);
}
camera.setParameters(params);
enableAutoFocusMode(camera);
}
}
private Runnable doFocusRunnable = new Runnable() {
#Override
public void run() {
if (camera != null) {
focusHandler.removeCallbacks(doFocusRunnable);
if (CameraPreview.isCameraPreviewStarted) {
try {
camera.autoFocus(autoFocusCallback);
logger.info("doFocusRunnable autofocus set");
} catch (Exception e) {
logger.error("Error while calling autofocus in camera."+e);
}
} else {
logger.info("doFocusRunnable isCameraPreviewStarted false. Postdelay for 2 seconds");
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
}
};
Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback(){
#Override
public void onAutoFocus(boolean arg0, Camera arg1) {
if (camera != null) {
logger.info("Excuting onAutoFocus callback");
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
};
public Camera getCameraInstance(Camera oldCamera) {
Camera newCamera = null;
try {
logger.info("attempt to get a Camera instance");
if (oldCamera == null) {
logger.info("oldCamera is null.Opening Camera");
newCamera = Camera.open(PRIMARY_CAMERA_ID);
} else {
logger.info("oldCamera is not null.Releasing it and Opening Camera");
oldCamera.release();
newCamera = Camera.open(PRIMARY_CAMERA_ID);
}
} catch (Exception e) {
logger.info("Camera is not available (in use or does not exist)");
}
return newCamera; // returns null if camera is unavailable
}
#Override
protected void onPause() {
super.onPause();
logger.info("onPause");
releaseCamera();
}
private void releaseCamera() {
if (null != camera) {
try {
focusHandler.removeCallbacks(doFocusRunnable);
CameraPreview.isCameraPreviewStarted = false;
camera.cancelAutoFocus();
camera.stopPreview();
camera.release();
camera = null;
cameraPreview.setVisibility(View.GONE);
cameraPreview = null;
inPreview = false;
logger.info("Camera released successfully ");
} catch (Exception e) {
logger.error("Error while releasing camera in releaseCamera()."+e);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
logger.info("onSaveInstanceState");
outState.putInt(DIntent.EXTRA_STOP_ID, stopId);
outState.putBoolean(DIntent.EXTRA_IS_IMAGE_CAPTURED, imageCaptured);
outState.putBoolean(DIntent.EXTRA_IN_PREVIEW, inPreview);
outState.putString(DIntent.EXTRA_IMAGE_DESC, imageDesc);
}
#Override
protected void onDestroy() {
super.onDestroy();
logger.info("onDestroy");
DeliverItApplication.getInstance().setImageCaptured(false);
}
public float getCameraDisplayOrientation(Activity activity, int cameraId) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraId, info);
int displayOrientation = activity.getWindowManager().getDefaultDisplay().getRotation();
int infoOrientation = info.orientation;
float degrees = 0;
switch (displayOrientation) {
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;
}
float result;
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
logger.info("Camera.CameraInfo.CAMERA_FACING_FRONT");
result = (infoOrientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
logger.info("Camera.CameraInfo.CAMERA_FACING_BACK");
result = (infoOrientation - degrees + 360) % 360;
}
logger.info("Display Rotation:" + displayOrientation + " & infoOrientation:" + infoOrientation + " & degrees:"
+ degrees + " & info.facing:" + info.facing + " & result:" + result);
return result;
}
private void captureImage() {
try {
if (camera != null) {
//camera.autoFocus(autoFocusCallback);
isCapturing = true;
logger.info("Taking picture while clicking Capture button");
camera.takePicture(null, null, pictureCallBack);
} else {
if (rotatedBitmap == null) {
showDialog(DIALOG_CAMERA_UNAVAILABLE);
}
}
} catch (Exception e) {
releaseCamera();
logger.error("Error in camera initialization in StartCaptureForPhoto screen.");
activatePreviewLayout();
activateCameraPreview();
}
}
private PictureCallback pictureCallBack = new PictureCallback() {
#Override
public void onPictureTaken(byte[] pData, Camera pCamera) {
BitmapFactory.Options bmFactoryOptions = new BitmapFactory.Options();
bmFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmFactoryOptions.inMutable = true;
// bmFactoryOptions.inSampleSize = 2;
Bitmap originalCameraBitmap = BitmapFactory.decodeByteArray(pData, 0, pData.length, bmFactoryOptions);
logger.info("before resized bitmap width : "+originalCameraBitmap.getWidth() + " Hieght : "+ originalCameraBitmap.getHeight());
rotatedBitmap = getResizedBitmap(originalCameraBitmap, cameraPreviewLayout.getHeight(), cameraPreviewLayout.getWidth() - preSizePriviewHight(), (int) rotationDegrees);
logger.info("cameraPreviewLayout width : "+cameraPreviewLayout.getWidth() + " Hieght : "+ cameraPreviewLayout.getHeight());
if (rotatedBitmap != null) {
imageCaptured = true;
activateCapturedImageView(rotatedBitmap);
} else {
imageCaptured = false;
}
isCapturing = false;
originalCameraBitmap.recycle();
flashToggle.setVisibility(View.GONE);
}
};
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight, int angle) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
DeliverItApplication.getInstance().setImageCaptured(true);
return resizedBitmap;
}
#Override
public void onClick(View pView) {
switch (pView.getId()) {
case R.id.btn_camera_capture:
if (!isCapturing) {
captureImage();
} else {
logger.error("Picture being captured.User clicked so fast.");
}
break;
case R.id.btn_camera_save:
if (imageCaptured) {
String description = imageDescEditText.getText().toString();
if (description != null && description.length() > 0) {
saveCapturedImage();
} else {
imageDescEditText.setError((getString(R.string.error_photo_desc)));
}
}
break;
case R.id.edit_captured_image:
colorContainerLayout.setVisibility(View.VISIBLE);
capturedImageUndo.setVisibility(View.VISIBLE);
editableCapturedImageview.setPaintBrushColor(Color.WHITE);
break;
case R.id.btn_markable_green:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#6AD523"));
break;
case R.id.btn_markable_blue:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#407FF0"));
break;
case R.id.btn_markable_red:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#B0321B"));
break;
case R.id.btn_markable_white:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#F7F5FA"));
break;
case R.id.btn_markable_black:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#2A2A2C"));
break;
case R.id.btn_undo:
editableCapturedImageview.onClickUndo();
break;
case R.id.btn_camera_cancel:
releaseCamera();
finish();
break;
case R.id.flashSwitch:
switchFlash();
default:
break;
}
}
#Override
protected Dialog onCreateDialog(int id, Bundle bundle) {
switch (id) {
case DIALOG_CAPTURE_EXCEPTION:
DIAlertDialog captureErrorDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_capture_exception).toString(), null, null);
return captureErrorDialog;
case DIALOG_SAVE_EXCEPTION:
DIAlertDialog imageSaveErrorDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_image_save_exception).toString(), null, null);
return imageSaveErrorDialog;
case DIALOG_CAPTURING_EXCEPTION:
DIAlertDialog capturingDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_capturing_exception).toString(), null, null);
return capturingDialog;
default:
return super.onCreateDialog(id, bundle);
}
}
private class ImageCaptureTopMenuListener implements OnClickListener {
#Override
public void onClick(View v) {
if (v.getVisibility() == View.VISIBLE && v.getId() == R.id.top_left_menu_item) {
onBackPressed();
} else if (v.getVisibility() == View.VISIBLE && v.getId() == R.id.top_right_menu_item) {
if (imageCaptured) {
String description = imageDescEditText.getText().toString();
if (description != null && description.length() > 0) {
saveCapturedImage();
} else {
imageDescEditText.setError((getString(R.string.error_photo_desc)));
}
}
}
}
}
private void switchFlash() {
if (camera == null) {
return;
}
if (!isFlashOn) {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
camera.setParameters(params);
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
isFlashOn = true;
} else {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
isFlashOn = false;
}
}
private int preSizePriviewHight() {
int defaultSize = 100;
switch (getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
defaultSize = 75;
break;
case DisplayMetrics.DENSITY_MEDIUM:
defaultSize = 80;
break;
case DisplayMetrics.DENSITY_HIGH:
defaultSize = 120;
break;
case DisplayMetrics.DENSITY_XHIGH:
defaultSize = 160;
break;
case DisplayMetrics.DENSITY_XXHIGH:
defaultSize = 430;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
defaultSize = 460;
break;
default:
break;
}
return defaultSize;
}
private void enableAutoFocusMode(Camera camera) {
try {
Camera.Parameters params = camera.getParameters();
List<String> focusParameterList = params.getSupportedFocusModes();
if (focusParameterList != null && focusParameterList.size() > 0) {
logger.info("Supported focus mode:"+focusParameterList);
if (focusParameterList.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
logger.info("enableAutoFocusMode: Starting focus mode");
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
/*
Below line commented due to crash issue in focus mode because of autoFocus call before start preview
So we are giving 2 sec delay for autoFocus.
*/
//camera.autoFocus(autoFocusCallback);
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
} catch (Exception e) {
logger.error("Error while setting AutoFocus in Camera."+e);
}
}
private boolean isFlashSupported(Camera.Parameters params) {
if (params != null) {
List<String> flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Camera.Parameters.FLASH_MODE_ON.equals(flashMode)) {
return true;
}
}
}
return false;
}
#Override
protected void onStop() {
super.onStop();
if (editableCapturedImageview != null) {
editableCapturedImageview.resetCanvas();
}
}
}
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static Logger logger = LoggerFactory.getLogger(CameraPreview.class);
private SurfaceHolder surfaceHolder;
private Camera camera;
private List<Size> cameraSizeList;
private Camera.Parameters cameraParameters;
public static boolean isCameraPreviewStarted = false;
public CameraPreview(Context context, Camera camera) {
super(context);
logger.info("Inside CameraPreview(Context context, Camera camera)");
this.camera = camera;
isCameraPreviewStarted = false;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
if (camera != null) {
logger.info("Camera Surface has been created, now tell the camera where to draw the preview.");
camera.setPreviewDisplay(holder);
camera.startPreview();
isCameraPreviewStarted = true;
}
} catch (IOException e) {
logger.error("Error occured in surfaceCreated.", e);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
logger.info("Camera SurfaceView Destroyed.");
isCameraPreviewStarted = false;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (surfaceHolder.getSurface() == null) {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged : preview surface does not exist");
}
return;
}
try {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged :stop preview before making resize/rotate/reformatting changes");
}
isCameraPreviewStarted = false;
camera.stopPreview();
} catch (Exception e) {
logger.error("onsurfaceChanged :Ignored surfaceChanged because tried to stop a non-existent preview", e);
}
if (camera != null) {
cameraParameters = camera.getParameters();
cameraSizeList = cameraParameters.getSupportedPreviewSizes();
cameraParameters.setPreviewSize(getMaxSupportedVideoSize().width, getMaxSupportedVideoSize().height);
surfaceHolder.setFixedSize(getMaxSupportedVideoSize().width, getMaxSupportedVideoSize().height);
camera.setParameters(cameraParameters);
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged : made resize/rotate/reformatting changes:preview size:"
+ String.valueOf(getMaxSupportedVideoSize().width) + ":"
+ String.valueOf(getMaxSupportedVideoSize().height));
}
}
try {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged :start preview with new settings");
}
if (camera != null) {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
logger.info("onsurfaceChanged :start preview with new settings");
isCameraPreviewStarted = true;
}
} catch (Exception e) {
logger.error("onsurfaceChanged :Error while resetting camera preview on surfaceChanged.", e);
}
}
public Size getMaxSupportedVideoSize() {
int maximum = cameraSizeList.get(0).width;
int position = 0;
for (int i = 0; i < cameraSizeList.size() - 1; i++) {
if (cameraSizeList.get(i).width > maximum) {
maximum = cameraSizeList.get(i).width; // new maximum
position = i - 1;
}
}
if (position == 0) {
int secondMax = cameraSizeList.get(1).width;
position = 1;
for (int j = 1; j < cameraSizeList.size() - 1; j++) {
if (cameraSizeList.get(j).width > secondMax) {
secondMax = cameraSizeList.get(j).width; // new maximum
position = j;
}
}
}
return cameraSizeList.get(position);
}
}

stretched image in custom camera using surfaceview

In some device the the image become stretched, I'm using surfaceView in may camera preview.
public class vp02ImageCapture extends SuperVP {
private static final String TAG = "vp02ImageCapture";
private Camera camera;
#Bind(R.id.TransparentView) SurfaceView transparentView;
#Bind(R.id.sv_camera) SurfaceView sv;
#Bind(R.id.relative) RelativeLayout rl;
#Bind(R.id.mask) FrameLayout mask;
private ProgressDialog dp;
private boolean front = true;
private SurfaceHolder sh,holderTransparent;
int orient = 1;
private Handler h = new Handler();
View v;
//private UserInfo info;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.vp02imagecapture, null);
ButterKnife.bind(this, v);
sh = sv.getHolder();
holderTransparent = transparentView.getHolder();
holderTransparent.setFormat(PixelFormat.TRANSPARENT);
transparentView.setZOrderMediaOverlay(true);
return v;
}
public int getscrOrientation()
{
Display getOrient = getActivity().getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
// Sometimes you may get undefined orientation Value is 0
// simple logic solves the problem compare the screen
// X,Y Co-ordinates and determine the Orientation in such cases
if(orientation==Configuration.ORIENTATION_UNDEFINED){
Configuration config = getResources().getConfiguration();
orientation = config.orientation;
if(orientation== Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(getOrient.getWidth()==getOrient.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(getOrient.getWidth() < getOrient.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
return orientation; // return value 1 is portrait and 2 is Landscape Mode
}
openCamera() method
private void openCamera() {
int cameraId;
if (front) {
cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
} else{
cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = getActivity().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;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
final Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
transparentView.requestLayout();
sv.requestLayout();
h.postDelayed(new Runnable() {
#Override
public void run() {
try {
Draw();
// camera.setParameters(parameters);
camera.setPreviewDisplay(sh);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}, 200);
}
#Override
public void releaseUI() {
rl.setVisibility(View.GONE);
// hideProgressDialog();
camera.release();
}
#Override
public void updateUI() {
super.updateUI();
Log.e("sample","asd " + TAG);
if (TAG.equals("vp02ImageCapture")){
parent.btnNext.setVisibility(View.GONE);
parent.btnBack.setVisibility(View.GONE);
}else{
parent.btnNext.setVisibility(View.VISIBLE);
parent.btnBack.setVisibility(View.VISIBLE);
}
getActivity().setTitle("Image Capture");
rl.setVisibility(View.VISIBLE);
openCamera();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isfront", front);
}
#OnClick(R.id.btnSwitch)void switchCamera(){
camera.stopPreview();
camera.release();
front = front ? false : true;
openCamera();
}
#OnClick(R.id.btnCapture) void capture(){
// showProgressDialog("Loading...");
camera.takePicture(new Camera.ShutterCallback() {
#Override
public void onShutter() {
}
}, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
}
}, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// rotate capture image
Display display = getActivity().getWindowManager().getDefaultDisplay();
int rotation = 0;
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
rotation = 90;
break;
case Surface.ROTATION_90:
rotation = 0;
break;
case Surface.ROTATION_180:
rotation = 270;
break;
case Surface.ROTATION_270:
rotation = 180;
break;
}
//Crop image size
Bitmap bitmap = ImageFactory.byteArrayToBitmap(data);
if (front) {
bitmap = rotate(bitmap, rotation);
}
int l = sv.getWidth() / 8;
int t = (sv.getHeight() / 2) - (l*4);
// 2.3 Size of rotated bitmap
int bitWidth = bitmap.getWidth();
int bitHeight = bitmap.getHeight();
Log.e("SIZES", "" + sv.getHeight() + "----" + bitHeight + "-----");
// 3. Size of camera preview on screen
int preWidth = sv.getWidth();
int preHeight = sv.getHeight();
// 4. Scale it.
// Assume you draw Rect as "canvas.drawRect(60, 50, 210, 297, paint);" command
// canvas.drawRect(l,t,l*7,t + l*8,paint1);
// int startx = (l * bitWidth / preWidth);
// int starty = (t * bitHeight / preHeight);
// int endx = ((l * 6) * bitWidth / preWidth);
// int endy = (((t * 4) * bitHeight / preHeight));
int startx = (l * bitWidth / preWidth);
int starty = (t * bitHeight / preHeight);
int endx = ((l * 6) * bitWidth / preWidth);
int endy = (((t + (l*7)) * bitHeight / preHeight));
Log.e("ELIBOY!", "" + l + "----" + t + "------" + l * 7 + "----" + t * 5);
Log.e("ELI!!!!", "" + startx + "----" + starty + "------" + endx + "----" + endy);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
setImageByteArray(byteArray);
setStartX(startx);
setStartY(starty);
setEndX(endx);
setEndY(endy);
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1); //set next page to display ; current page + 1
/*Fragment f = new vp03ImagePreview();
f.setArguments(b);
getParentFragment().getChildFragmentManager().beginTransaction().replace(R.id.imagefrag_container,f).commit();*/
//ScreenManager.getInstance().replaceScreen(Screens.Enroll02b,b);
}
});
}
boolean fromPause = false;
#Override
public void onResume() {
super.onResume();
if(fromPause)
if(((ScreenTransaction)getParentFragment()).viewPager.getCurrentItem()==1)
openCamera();
fromPause = false;
}
#Override
public void onPause() {
super.onPause();
try{
camera.release();
}catch (NullPointerException e){
}
h.removeCallbacksAndMessages(null);
fromPause = true;
//viewPager.removeOnPageChangeListener(viewpagerChangeListener);
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.5;
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.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
#OnClick(R.id.mask)void autofocus(){
camera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
public void showProgressDialog(String message){
dp = new ProgressDialog(getActivity());
dp.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dp.setCancelable(false);
dp.setMessage(message);
dp.show();
}
public void hideProgressDialog(){
dp.hide();
}
}
I want to support all screen .
How can I solve this?
in some screen its working but in some specially when its default camera is not in full screen.
I have made this code and its working very well.
public class CameraActivity extends Activity implements Constants.Parameters {
FrameLayout previewFrameLayout;
ImageButton captureButton, switchCamera, flashImageButton, backImageButton;
boolean isFlashEnabled = false, isFlashAvailable = false, isFrontCamera = false;
Handler handler;
private int mCameraId;
private Camera mCamera;
private CameraPreview mCameraPreview;
public final int BACK_CAMERA = 0;
public final int FRONT_CAMERA = 1;
String className = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
handler = new Handler();
isFlashAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
isFrontCamera = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
previewFrameLayout = (FrameLayout) findViewById(R.id.camera_preview);
captureButton = (ImageButton) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
switchCamera = (ImageButton) findViewById(R.id.switchCamera);
switchCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Utils.scaleView(switchCamera);
handler.postDelayed(new Runnable() {
#Override
public void run() {
previewFrameLayout.removeAllViews();
if (mCameraId == BACK_CAMERA) {
flashImageButton.setVisibility(View.INVISIBLE);
mCameraId = FRONT_CAMERA;
mCameraPreview = new CameraPreview(CameraNewActivity.this, FRONT_CAMERA);
previewFrameLayout.addView(mCameraPreview);
} else {
flashImageButton.setVisibility(View.VISIBLE);
mCameraId = BACK_CAMERA;
mCameraPreview = new CameraPreview(CameraNewActivity.this, BACK_CAMERA);
previewFrameLayout.addView(mCameraPreview);
}
}
}, 250);
}
});
flashImageButton = (ImageButton) findViewById(R.id.flash);
flashImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Utils.scaleView(flashImageButton);
try {
Camera.Parameters parameters = mCamera.getParameters();
if (!isFlashEnabled) {
isFlashEnabled = true;
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
flashImageButton.setSelected(true);
} else {
isFlashEnabled = false;
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
flashImageButton.setSelected(false);
}
mCamera.setParameters(parameters);
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (!isFlashAvailable) {
flashImageButton.setVisibility(View.GONE);
}
if (!isFrontCamera) {
switchCamera.setVisibility(View.GONE);
}
backImageButton = (ImageButton) findViewById(R.id.back);
backImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void hideIcons() {
switchCamera.setVisibility(View.GONE);
captureButton.setVisibility(View.GONE);
flashImageButton.setVisibility(View.GONE);
backImageButton.setVisibility(View.GONE);
}
private void showIcons() {
switchCamera.setVisibility(View.VISIBLE);
captureButton.setVisibility(View.VISIBLE);
flashImageButton.setVisibility(View.VISIBLE);
backImageButton.setVisibility(View.VISIBLE);
}
#Override
protected void onResume() {
super.onResume();
mCameraPreview = new CameraPreview(this, mCameraId);
previewFrameLayout.addView(mCameraPreview);
}
#Override
protected void onPause() {
super.onPause();
mCameraPreview.stop();
previewFrameLayout.removeView(mCameraPreview); // This is necessary.
mCameraPreview = null;
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
final File pictureFile = new File(Utils.profilePicPath + String.valueOf(System.currentTimeMillis()) + ".jpg");
pictureFile.getParentFile().mkdirs();
Utils.deleteCapture();
if (pictureFile == null) {
return;
}
Thread thread = new Thread() {
#Override
public void run() {
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pictureFile.getPath(), bmOptions);
final int height = bmOptions.outHeight;
final int width = bmOptions.outWidth;
if (height > width) {
if (height / width < 1.5) {
Bitmap bitmap = Picasso.with(CameraNewActivity.this)
.load(pictureFile).resize((int) (height / 1.65), height).centerCrop().get();
if (mCameraId == FRONT_CAMERA) {
bitmap = flip(bitmap);
}
FileOutputStream out = new FileOutputStream(pictureFile.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
};
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
private int mSurfaceChangedCallDepth = 0;
private int mCenterPosX = -1;
private int mCenterPosY = 0;
protected boolean mSurfaceChanged = false;
public CameraPreview(Activity activity, int cameraId) {
super(activity);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (Camera.getNumberOfCameras() > cameraId) {
mCameraId = cameraId;
} else {
mCameraId = 0;
}
mCamera = Camera.open(mCameraId);
Camera.Parameters cameraParams = mCamera.getParameters();
mPreviewSizeList = cameraParams.getSupportedPreviewSizes();
mPictureSizeList = cameraParams.getSupportedPictureSizes();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceChangedCallDepth++;
mCamera.stopPreview();
Camera.Parameters cameraParams = mCamera.getParameters();
if (!mSurfaceChanged) {
Camera.Size previewSize = determinePreviewSize(width, height);
Camera.Size pictureSize = determinePictureSize(previewSize);
mPreviewSize = previewSize;
mPictureSize = pictureSize;
mSurfaceChanged = adjustSurfaceLayoutSize(previewSize, width, height);
if (mSurfaceChanged && (mSurfaceChangedCallDepth <= 1)) {
return;
}
}
if (mCameraId == BACK_CAMERA) {
cameraParams.setRotation(90);
} else {
cameraParams.setRotation(270);
}
mCamera.setDisplayOrientation(90);
cameraParams.set("orientation", "portrait");
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
mCamera.setParameters(cameraParams);
mSurfaceChanged = false;
try {
mCamera.startPreview();
} catch (Exception e) {
// Remove failed size
mPreviewSizeList.remove(mPreviewSize);
mPreviewSize = null;
// Reconfigure
if (mPreviewSizeList.size() > 0) { // prevent infinite loop
surfaceChanged(null, 0, width, height);
} else {
Utils.showToast(CameraNewActivity.this, "Can't start preview", Toast.LENGTH_LONG);
}
}
mSurfaceChangedCallDepth--;
}
protected Camera.Size determinePreviewSize(int reqWidth, int reqHeight) {
int reqPreviewWidth = reqHeight; // requested width in terms of camera hardware
int reqPreviewHeight = reqWidth; // requested height in terms of camera hardware
// Adjust surface size with the closest aspect-ratio
float reqRatio = ((float) reqPreviewWidth) / reqPreviewHeight;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
Camera.Size retSize = null;
for (Camera.Size size : mPreviewSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected Camera.Size determinePictureSize(Camera.Size previewSize) {
Camera.Size retSize = null;
for (Camera.Size size : mPictureSizeList) {
if (size.equals(previewSize)) {
return size;
}
}
// if the preview size is not supported as a picture size
float reqRatio = ((float) previewSize.width) / previewSize.height;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
for (Camera.Size size : mPictureSizeList) {
curRatio = ((float) size.width) / size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize,
int availableWidth, int availableHeight) {
float tmpLayoutHeight = previewSize.width;
float tmpLayoutWidth = previewSize.height;
float factH, factW, fact;
factH = availableHeight / tmpLayoutHeight;
factW = availableWidth / tmpLayoutWidth;
if (factH < factW) {
fact = factH;
} else {
fact = factW;
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) this.getLayoutParams();
int layoutHeight = (int) (tmpLayoutHeight * fact);
int layoutWidth = (int) (tmpLayoutWidth * fact);
boolean layoutChanged;
if ((layoutWidth != this.getWidth()) || (layoutHeight != this.getHeight())) {
layoutParams.height = layoutHeight;
layoutParams.width = layoutWidth;
if (mCenterPosX >= 0) {
layoutParams.topMargin = mCenterPosY - (layoutHeight / 2);
layoutParams.leftMargin = mCenterPosX - (layoutWidth / 2);
}
this.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation.
layoutChanged = true;
} else {
layoutChanged = false;
}
return layoutChanged;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
stop();
}
public void stop() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
}
public Bitmap flip(Bitmap bitmap) {
Matrix mtx = new Matrix();
mtx.preScale(-1, 1);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true);
}
}

android custom camera orientation issue [duplicate]

This question already has answers here:
Camera preview is in portrait mode but image captured is rotated
(3 answers)
Closed 6 years ago.
I have defined a custom camera view to take picture.
The issue i am getting is if the picture is taken with camera held in "portrait" , the image is 90 rotated. If i take the picture in "landscape" mode, it is getting correct .
My code is below . I tried few solutions like Android - Camera preview is sideways
but it didnt fix my problem.
Please give me some directions.
Thanks.
public class Customcamera extends Activity implements OnClickListener {
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
Bitmap bmp;
static Bitmap mutableBitmap;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
File imageFileName = null;
File imageFileFolder = null;
private MediaScannerConnection msConn;
Display d;
int screenhgt, screenwdh;
ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preview);
preview = (SurfaceView) findViewById(R.id.surface);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
previewHolder.setFixedSize(getWindow().getWindowManager()
.getDefaultDisplay().getWidth(), getWindow().getWindowManager()
.getDefaultDisplay().getHeight());
}
#Override
public void onResume() {
super.onResume();
camera = Camera.open();
setCameraDisplayOrientation(this, 0, camera);
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height,
Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return (result);
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(Customcamera.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height, parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
setCameraDisplayOrientation(Customcamera.this, 0, camera);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(final byte[] data, final Camera camera) {
Log.i("onPictureTaken", "onPictureTaken");
dialog = ProgressDialog.show(Customcamera.this, "", "Saving Photo");
/*
* new Thread() { public void run() { try { // Thread.sleep(1000); }
* catch (Exception ex) { } onPictureTake(data, camera); }
* }.start();
*/
onPictureTake(data, camera);
}
};
public void onPictureTake(byte[] data, Camera camera) {
if (mutableBitmap != null) {
mutableBitmap.recycle();
}
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
savePhoto(mutableBitmap);
showPhoto();
dialog.dismiss();
}
private void showPhoto() {
Intent intent = new Intent(this, EditAndPostActivity.class);
startActivity(intent);
}
class SavePhotoTask extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(),
"photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return (null);
}
}
public void savePhoto(Bitmap bmp) {
imageFileFolder = new File(Environment.getExternalStorageDirectory(),
"Unipyx");
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH))
+ fromInt(c.get(Calendar.DAY_OF_MONTH))
+ fromInt(c.get(Calendar.YEAR))
+ fromInt(c.get(Calendar.HOUR_OF_DAY))
+ fromInt(c.get(Calendar.MINUTE))
+ fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
scanPhoto(imageFileName.toString());
out = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public String fromInt(int val) {
return String.valueOf(val);
}
public void scanPhoto(final String imageFileName) {
msConn = new MediaScannerConnection(Customcamera.this,
new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
Log.i("msClient obj in Photo Utility",
"connection established");
}
public void onScanCompleted(String path, Uri uri) {
msConn.disconnect();
Log.i("msClient obj in Photo Utility", "scan completed");
}
});
msConn.connect();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {
onBack();
}
return super.onKeyDown(keyCode, event);
}
public void onBack() {
Log.e("onBack :", "yes");
camera.takePicture(null, null, photoCallback);
inPreview = false;
}
#Override
public void onClick(View v) {
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.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;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
When you convert the byte[] to a Bitmap in onPictureTake(), you are throwing away the orientation information included in the byte array. You should instead directly write the bytes to a File if you want to save the orientation information.

Categories

Resources