Answer the question
In order to leave comments, you need to log in
Why is the photo from the front camera turned upside down?
I implement in my application the ability to take photos from the front / rear camera. Here is the implementation code:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder holder;
Camera camera;
Context context;
Camera.Size bestSize;
static int cameraId;
public CameraPreview(Context context, Camera camera) {
super(context);
this.context = context;
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
}
catch (IOException e) {
e.printStackTrace();
Log.d("camera", "All is terrible");
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
prepareCamera();
launchPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
public int getCorrectCameraOrientation() {
int rotation = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE))
.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);
// back cam
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
result = ((360 - degrees) + info.orientation);
} else {
// front cam
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = ((360 - degrees) - info.orientation);
result += 360;
}
}
return result % 360;
}
static public Observable<Camera> createCamera(int cameraId){
CameraPreview.cameraId = cameraId;
// open front or rear camera, depends on cameraId
Observable<Camera> cameraObservable = Observable.create(
s -> {
Camera camera = null;
if(Camera.getNumberOfCameras() > 1)
camera = Camera.open(cameraId);
else {
// return front camera if not rear
camera = Camera.open(1);
}
s.onNext(camera);
s.onCompleted();
});
return cameraObservable;
}
private void launchPreview(){
try
{
camera.setPreviewDisplay(holder);
camera.startPreview();
}
catch(Exception e)
{
Log.d("CAMERA", "Error: " + e.getMessage());
}
}
private void getBestPictureResolution(){
List<Camera.Size> sizes = camera.getParameters().getSupportedPictureSizes();
Camera.Size result = sizes.get(0);
for (Camera.Size size: sizes) {
if(size.width > result.width && size.height > result.height) {
result = size;
}
}
bestSize = result;
}
private void setOptimalPreviewSize() {
Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
Camera.Size size = camera.getParameters().getPreviewSize();
RectF rectDisplay = new RectF();
RectF rectPreview = new RectF();
rectDisplay.set(0, 0, display.getWidth(), display.getHeight());
rectPreview.set(0, 0, size.height, size.width);
Matrix matrix = new Matrix();
matrix.setRectToRect(rectPreview, rectDisplay,
Matrix.ScaleToFit.START);
matrix.mapRect(rectPreview);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
lp.height = (int) (rectPreview.bottom);
lp.width = (int) (rectPreview.right);
setLayoutParams(lp);
requestLayout();
}
private void prepareCamera(){
if(camera != null)
camera.stopPreview();
Camera.Parameters params = camera.getParameters();
if(bestSize == null)
getBestPictureResolution();
params.setPictureSize(bestSize.width, bestSize.height);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
camera.setDisplayOrientation(getCorrectCameraOrientation());
params.setRotation(getCorrectCameraOrientation());
setOptimalPreviewSize();
camera.setParameters(params);
}
}
Answer the question
In order to leave comments, you need to log in
Faced a similar problem recently. Some phones (Samsung in my case) can change the photo orientation themselves. Because of this, a photo taken from the gallery was rotated in my ImageView. To fix this, I used such a crutch - onActivityResult () gets a photo that was selected from the gallery and in the getImageOrientation () method I set the desired orientation.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("myLogs", "requestCode = " + requestCode + ", resultCode = " + resultCode);
if (requestCode == 999 && resultCode == Activity.RESULT_OK)
try {
Matrix matrix = new Matrix();
matrix.postRotate(getImageOrientation(data));
if (mAvatarBitmap != null) mAvatarBitmap.recycle();
InputStream stream = getActivity().getContentResolver().openInputStream(data.getData());
mAvatarBitmap = BitmapFactory.decodeStream(stream);
if (stream != null) stream.close();
Bitmap rotatedBitmap = Bitmap.createBitmap(mAvatarBitmap, 0, 0, mAvatarBitmap.getWidth(), mAvatarBitmap.getHeight(), matrix, true);
storeImage(rotatedBitmap);
setLogo();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private int getImageOrientation(Intent data) {
Uri imageUri = data.getData();
String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = getActivity().getContentResolver().query(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
Log.d("orientation", "Picture orientation: " + orientation);
} else {
Log.d("orientation", "Wrong picture orientation: " + orientation);
}
if (cur != null) cur.close();
return orientation;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question