Picture taken from camera displayed in ImageView is always horizontal Android - android

I am using the following code to take a picture and then display it on screen to the user using an ImageView. I want the picture to be displayed fullscreen (like on snapchat). However, the picture is always displayed like this horizontally with a white screen everywhere else:
This is my layout:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:id="#+id/picturedisplay"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgClose"
android:layout_gravity="right|bottom"
android:text="Flip Cam"
android:padding="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/snap"
android:text="Capture"
android:layout_gravity="center|bottom"
android:padding="20dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Flash"
android:id="#+id/imgOpen"
android:layout_gravity="left|bottom"
android:padding="20dp"/>
and the code:
public class CameraScreen extends Activity {
private Camera mCamera = null;
private SessionManager session;
private String rand_img;
private ImageView preview_pic;
private Bitmap bitmap;
private CameraPreview mCameraView = null;
private byte[] photo;
static final int CAM_REQUEST = 1;
private RandomString randomString = new RandomString(10);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_screen);
session = new SessionManager(getApplicationContext());
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
//btn to close the application
Button imgClose = (Button) findViewById(R.id.imgClose);
imgClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.exit(0);
}
});
//btn to close the application
Button logout = (Button) findViewById(R.id.imgOpen);
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
session.logOut();
Intent a = new Intent(CameraScreen.this, MainActivity.class);
startActivity(a);
finish();
}
});
Button snap = (Button) findViewById(R.id.snap);
snap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
});
}
#Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraView.getHolder().removeCallback(mCameraView);
mCamera.release();
}
}
#Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera initialization
}
}
protected void initializeCamera(){
// Get an instance of Camera Object
try{
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e){
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
private File getFile() {
File sdCard = Environment.getExternalStorageDirectory();
File folder = new File(sdCard.getAbsolutePath() +"/city_life_pic");
if (!folder.exists()) {
folder.mkdir();
}
rand_img = randomString.nextString() + ".jpg";
File image = new File(folder,rand_img);
return image;
}
Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
Log.d("ON SHUTTER", "onShutter'd");
}
};
Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("ON PICTURE RAW", "onPictureTaken - raw");
}
};
Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
photo = data;
new SaveImageTask().execute(data);
Log.d("ON PICTURE JPEG", "onPictureTaken - jpeg");
}
};
private class SaveImageTask extends AsyncTask<byte[], Void, Void> {
#Override
protected Void doInBackground(byte[]... data) {
FileOutputStream outStream = null;
// Write to SD Card
try {
bitmap = decodeByteArray(photo, 0, photo.length);
File outFile = getFile();
outStream = new FileOutputStream(outFile);
outStream.write(data[0]);
ExifInterface exif=new ExifInterface(outFile.toString());
Log.d("EXIF value", exif.getAttribute(ExifInterface.TAG_ORIENTATION));
if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")){
bitmap= rotate(bitmap, 90);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")){
bitmap= rotate(bitmap, 270);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")){
bitmap= rotate(bitmap, 180);
} else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("0")){
bitmap= rotate(bitmap, 90);
}
boolean bo = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
preview_pic = (ImageView) findViewById(R.id.picturedisplay);
camera_view.setVisibility(View.GONE);
preview_pic.setVisibility(View.VISIBLE);
preview_pic.setImageBitmap(bitmap);
}
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
// mtx.postRotate(degree);
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
}
EDIT ROTATION CODE:
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;
}
if (currentCamInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
//switch camera to back camera
mCamera = Camera.open(camBackId);
result = (currentCamInfo.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else {
//switch camera to front camera
mCamera = Camera.open(camFrontId);
result = (currentCamInfo.orientation - degrees + 360) % 360;
}
if (mCamera != null) {
mCamera.setDisplayOrientation(result);
//rotate camera
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
camera_view.addView(mCameraView);//add the SurfaceView to the layout
Camera.Parameters p = mCamera.getParameters();
p.setRotation(90);
mCamera.setParameters(p);
}

Try adding mCamera.setDisplayOrientation(90) to your initializeCamera() method. You can also calculate the right orientation settings based on this code.
public static int getCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = Session.currentActivity.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;
}
return result;
}

Related

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!

Android Camera Image Quality Very Low

I am trying to capture an image from camera but the image quality is really bad. I don't know why as I am a newbie to coding for android.
I have tried a couple of things but didn't worked out. Here is my code. Please help me where to change the code.
public class MainActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;
private TextureView mTextureView1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextureView1 = (TextureView) findViewById(R.id.textureView1);
mTextureView1.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
try {
mCamera = Camera.open(getCameraId());
mCamera.setPreviewTexture(surface);
Camera.Parameters params=mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
for(int i=0;i<sizes.size();i++)
{
if(sizes.get(i).width > size.width)
size = sizes.get(i);
}
params.setPictureSize(size.width, size.height);
params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
params.setExposureCompensation(0);
params.setPictureFormat(ImageFormat.JPEG);
params.setJpegQuality(100);
params.setRotation(90);
params.setJpegQuality(100);
params.setPreviewSize(size.width, size.height);
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(getCameraId(), cameraInfo);
setCameraDisplayOrientation(this, getCameraId(), mCamera);
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
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);
}
private int getCameraId() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
// Log.d(DEBUG_TAG, "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
try {
mCamera.stopPreview();
mCamera.release();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
Camera.PictureCallback mPicture = new Camera.PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private static File getOutputMediaFile(int mediaTypeImage) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
public void onClick(View v){
mCamera.takePicture(null, null, mPicture);
}
}
Which is way lower than 13 megapixel camera in my phone.

Android camera app freezes black screen after onResume()

I am developing an app that is going to be something like camscanner. In my app i have an camera api tha i call. When the app is first opened and i press the camera button it works, but when i click home button and open again my app it freezes and shows a black screen without the app crashing. I found similar questions but none could give me a right answer, i know i probably have to change something in the onResume or onPause and need help to figure out what.
below i have my CameraScreen activity:
public class CameraScreen extends Activity {
ImageView image;
Activity context;
Preview preview;
Camera camera;
Button exitButton;
ImageView fotoButton;
LinearLayout progressLayout;
String path = "/sdcard/KutCamera/cache/images/";
FrameLayout frame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
context=this;
fotoButton = (ImageView) findViewById(R.id.imageView_foto);
exitButton = (Button) findViewById(R.id.button_exit);
image = (ImageView) findViewById(R.id.imageView_photo);
progressLayout = (LinearLayout) findViewById(R.id.progress_layout);
preview = new Preview(this,
(SurfaceView) findViewById(R.id.KutCameraFragment));
frame = (FrameLayout) findViewById(R.id.preview);
frame.addView(preview);
preview.setKeepScreenOn(true);
fotoButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
takeFocusedPicture();
} catch (Exception e) {
}
exitButton.setClickable(true);
fotoButton.setClickable(false);
progressLayout.setVisibility(View.VISIBLE);
}
});
}
#Override
protected void onPause() {
super.onPause();
//releaseMediaRecorder(); // if you are using MediaRecorder, release it first
//releaseCamera();
if(null != camera){
camera.release();
camera = null;
}
frame.removeView(preview);
preview = null;// release the camera immediately on pause event
}
private void releaseCamera(){
if (camera != null){
camera.release(); // release the camera for other applications
camera = null;
}
}
#Override
protected void onResume() {
super.onResume();
// TODO Auto-generated method stub
if(camera==null){
Log.d("Camera tes", "Camera==null");
//camera.setPreviewCallback(null);
camera = Camera.open();
camera.startPreview();
camera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera mcamera) {
camera.release();
camera = Camera.open();
Log.d("Camera died", "error camera");
}
});
}
if (camera != null) {
//camera.setPreviewCallback(null);
Log.d("Camera tes", "Camera!=null");
if (Build.VERSION.SDK_INT >= 14)
setCameraDisplayOrientation(context,
CameraInfo.CAMERA_FACING_BACK, camera);
preview.setCamera(camera);
}
}
private 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);
}
Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
try{
camera.takePicture(mShutterCallback, null, jpegCallback);
}catch(Exception e){
}
}
};
Camera.ShutterCallback mShutterCallback = new ShutterCallback() {
#Override
public void onShutter() {
// TODO Auto-generated method stub
}
};
public void takeFocusedPicture() {
camera.autoFocus(mAutoFocusCallback);
}
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// Log.d(TAG, "onPictureTaken - raw");
}
};
PictureCallback jpegCallback = new PictureCallback() {
#SuppressWarnings("deprecation")
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
Calendar c = Calendar.getInstance();
File videoDirectory = new File(path);
if (!videoDirectory.exists()) {
videoDirectory.mkdirs();
}
try {
// Write to SD Card
outStream = new FileOutputStream(path + c.getTime().getSeconds() + ".jpg");
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Bitmap realImage;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
options.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
options.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
realImage = BitmapFactory.decodeByteArray(data,0,data.length,options);
ExifInterface exif = null;
try {
exif = new ExifInterface(path + c.getTime().getSeconds()
+ ".jpg");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Log.d("EXIF value",
exif.getAttribute(ExifInterface.TAG_ORIENTATION));
if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("1")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("8")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("3")) {
realImage = rotate(realImage, 90);
} else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
.equalsIgnoreCase("0")) {
realImage = rotate(realImage, 90);
}
} catch (Exception e) {
}
image.setImageBitmap(realImage);
fotoButton.setClickable(true);
camera.startPreview();
progressLayout.setVisibility(View.GONE);
exitButton.setClickable(true);
}
};
public static Bitmap rotate(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}
}
And here i have my Preview class:
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
int heightmax ;
int widthmax ;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
#SuppressWarnings("deprecation")
Preview(Context context, SurfaceView sv) {
super(context);
mSurfaceView = sv;
// addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPictureSizes();
requestLayout();
// get Camera parameters
Camera.Parameters params = mCamera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);
}
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize=maxSize();
}
}
public Size maxSize(){
Size sizeMax=mSupportedPreviewSizes.get(0);
maxsize=mSupportedPreviewSizes.get(0)
.height*mSupportedPreviewSizes.get(0).width;
for(Size size:mSupportedPreviewSizes){
if(size.height*size.width>sizeMax.width*sizeMax.height){
sizeMax = size;
}
}
return sizeMax;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
/*
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
if (mCamera != null) {
mCamera.stopPreview();
}
*/
}
Camera.AutoFocusCallback mnAutoFocusCallback = new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
}
};
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
/*
if(mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
mCamera.startPreview();
}
*/
}
}
I would appriciate any help or guides you can give me.

Camera preview is in portrait mode but image captured is rotated

I am trying to capture a photo using the camera. The preview by default was in landscape mode which i could change it to portrait mode using
setCameraDisplayOrientation(this,1, mCamera);
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);
}
The image captured is stored under a folder myImages. But the images is rotated. (look's like the image is captured in landscape mode)
So how can i rotate the image captured and save the same?
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 1;
ImageView imageView;
Button b;
private Camera mCamera;
private CameraPreview mPreview;
private Bitmap bitmap;
private PictureCallback mPicture;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boolean check =checkCameraHardware(MainActivity.this);
if(check)
{
mCamera = getCameraInstance();
// mCamera.setDisplayOrientation(90);
setCameraDisplayOrientation(this,
1, mCamera);//requires min sdk 9
}
// Create an instance of Camera
mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
if(!imagesFolder.exists())
imagesFolder.mkdirs();
File pictureFile = new File(imagesFolder, "image.jpg");
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
System.out.println("hello");
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("No File", "File not found: " + e.getMessage());
} catch (IOException e) {
//Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
b = (Button) findViewById(R.id.button_capture);
b.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, null, mPicture);
Toast.makeText(MainActivity.this, "Called",1000).show();
}
});
}
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);
}
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
Toast.makeText(this, "Phone has camera", Toast.LENGTH_LONG).show();
return true;
} else {
// no camera on this device
Toast.makeText(this, "Phone has no camera", Toast.LENGTH_LONG).show();
return false;
}
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mCamera.release();
}
}
The CameraPreview class is the same from the developer site http://developer.android.com/guide/topics/media/camera.html
Note: I am using the back camera not the front facing camera.
I faced the same problem when taking photo from camera in portrait mode. Below lines of code solved my problem:
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);
}
Call setCameraDisplayOrientation() method in surfaceCreated callback as the following:
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
setCameraDisplayOrientation(getActivity(), CameraInfo.CAMERA_FACING_BACK, camera);
}
I had to rotate the image in Camera onPictureTaken() callback:
camera.takePicture(null, null, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
Bitmap bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
bm=scaled;
}
photoPreview.setImageBitmap(bm);
}
isImageCaptured = true;
photoPreview.setVisibility(View.VISIBLE);
surfaceView.setVisibility(View.GONE);
}
});
Below code worked for me for Front facing camera.
if (data != null) {
try {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
bm = BitmapFactory.decodeByteArray(data, 0,
(data != null) ? data.length : 0);
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraFace, info);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
// Bitmap scaled = Bitmap.createScaledBitmap(bm,
// screenHeight, screenWidth, true);
// int w = scaled.getWidth();
// int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
if (cameraFace == CameraInfo.CAMERA_FACING_FRONT)
mtx.postRotate(180);
// Rotating Bitmap
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), mtx, true);
} else {// LANDSCAPE MODE
Bitmap scaled = Bitmap.createScaledBitmap(bm,
screenWidth, screenHeight, true);
bm = scaled;
}
} catch (Exception e) {
} catch (Error e) {
}
}
Yes, I tried the way in the answer, it works for back camera, for front camera, it need to rotate 270 not 90. :)

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