simfrek
simfrek

Reputation: 39

camera app rotates images by 90 degrees

my custom camera app i am developing rotates the images by 90 degrees all the time, the onscreen view of my camera is distorted and in 90 degrees anti-clockwise, however when it saves the image, it is as if i have taken the photo with my phone 90 degrees to the left when im holding it portrait, it takes landscape photos. here is the code from the camera activity, what can i do to rotate the onscreen view of my camera?

package fr.altimer.lost.collect.client;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.location.Location;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.Toast;
import fr.altimer.lost.collect.client.model.Data;
import fr.altimer.lost.collect.client.model.Image;
import fr.altimer.lost.collect.client.preferences.Configuration;
import fr.altimer.lost.collect.client.services.SearchService;
import fr.altimer.lost.collect.client.services.ServiceSensor;

public class CameraActivity extends Activity implements SurfaceHolder.Callback, Camera.PictureCallback {

private Camera camera;
private SurfaceView surfaceCamera;
private Boolean isPreview;
private ServiceSensor mService;
private boolean mBound;

private int routeGiven = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // On met l'application en plein écran et sans barre de titre
    getWindow().setFormat(PixelFormat.TRANSLUCENT);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    isPreview = false;

    // On applique notre layout
    setContentView(R.layout.camera);

    // On récupère notre surface pour le preview
    surfaceCamera = (SurfaceView) findViewById(R.id.surfaceViewCamera);

    // Bouton pour prendre la photo
    ImageButton picture = (ImageButton) findViewById(R.id.photo);
    picture.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            takepicture();
        }
    });

    // Bouton retour
    ImageButton back = (ImageButton) findViewById(R.id.TableLayout02);
    back.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            finish();
        }
    });

    // Méthode d'initialisation de la caméra
    InitializeCamera();

    if (savedInstanceState != null) {
        routeGiven = savedInstanceState.getInt("routeGiven", 0);
    }
}

public void InitializeCamera() {
    // On attache nos retour du holder à  notre activite
    surfaceCamera.getHolder().addCallback(this);
    surfaceCamera.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // Si le mode preview est lancé alors on le stop
    if (isPreview) {
        camera.stopPreview();
    }
    // On récupère les parametres de la camera
    Camera.Parameters parameters = camera.getParameters();

    List<Size> sizes = parameters.getSupportedPreviewSizes();
    Size previewSize = getOptimalPreviewSize(sizes, width, height);
    // On change la taille
    parameters.setPreviewSize(previewSize.width, previewSize.height);

    // On applique nos nouveaux parametres
    camera.setParameters(parameters);

    try {
        // On attache notre previsualisation de la camera au holder de la
        // surface
        camera.setPreviewDisplay(surfaceCamera.getHolder());
    } catch (IOException e) {
    }

    // On lance la previeuw
    camera.startPreview();

    isPreview = true;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // On prend le controle de la camera
    if (camera == null)
        camera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // On arrête la camera et on rend la main
    if (camera != null) {
        camera.stopPreview();
        isPreview = false;
        camera.release();
    }
}

@Override
public void onPictureTaken(byte[] data, Camera camera) {
    int routeid = 0;

    // récupération de l'id du parcours
    if (mBound && mService != null) {
        routeid = mService.getIdCurrent();
    } else {
        routeid = routeGiven;
    }

    // Création et sauvegarde la photo
    String pictureName = getFileName(routeid);

    if (pictureName != null) {
        File pictureFile = new File(pictureName);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.flush();
            Toast.makeText(getBaseContext(), "New Image saved", Toast.LENGTH_LONG).show();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // Enregistrement du path de l'image dans la bdd
        if (mBound && mService != null) {
            Location loc = mService.getLastLocation();
            Data image;
            if (loc == null)
                image = new Image(pictureName, null, null);
            else
                image = new Image(pictureName, loc.getLatitude(), loc.getLongitude());
            mService.saveData(image);
        } else {
            Intent intent = new Intent();
            intent.putExtra("path", pictureName);
            setResult(RESULT_OK, intent);
        }
    } else {
        Toast.makeText(this, "Can't create directory to save image.", Toast.LENGTH_LONG).show();
    }
    finish();
}

/**
 * Récupération du chemin de la carte SD
 * @return
 */
private File getDir() {
    String status = Environment.getExternalStorageState();
    try {
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            return Environment.getExternalStorageDirectory();
        }
    } catch (IllegalArgumentException e) {
        status = Environment.MEDIA_REMOVED;
    }
    return null;
}

/**
 * Création et récupération du nom du fichier jpg
 * @param routeid
 * @return
 */
private String getFileName(int routeid) {
    SimpleDateFormat dateFormat1 = new SimpleDateFormat("ddMMyy-HHmmss");
    String dateString = dateFormat1.format(new Date());
    File fileDir = getDir();
    if (fileDir != null) {
        File filePath = new File(fileDir.getAbsolutePath() + Configuration.LOST_FOLDER);
        if (!filePath.exists())
            filePath.mkdir();
        return filePath.getPath() + File.separator + "Picture_" + dateString + "_id_" + routeid + ".jpg";
    } else {
        return null;
    }
}

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    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;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (KeyEvent.KEYCODE_CAMERA == keyCode /* && event.isLongPress() */) {
        takepicture();
        return true;
    }
    if (KeyEvent.KEYCODE_BACK == keyCode) {
        finish();
        return true;
    }
    return false;
}

private void takepicture() {
    camera.takePicture(null, null, this);
}

private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        mService = ((ServiceSensor.LocalBinder) service).getService();
        mService.setHandler(null);

        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

@Override
protected void onStart() {
    super.onStart();
    Intent intent = new Intent(this, ServiceSensor.class);
    if (SearchService.Search(this, "ServiceSensor")) {
        bindService(intent, mConnection, Context.BIND_NOT_FOREGROUND);
    }
}

@Override
protected void onStop() {
    super.onStop();
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}
}

(the comments are in french occasionally as i am working with a french colleague, although i don't speak french much.)

Upvotes: 0

Views: 2638

Answers (3)

redIntent
redIntent

Reputation: 134

in your manifest file add this line in your activity: android:screenOrientation="landscape"

Upvotes: -1

AAnkit
AAnkit

Reputation: 27549

This is my implementation of surfaceCreated method of SurfaceHolder.Callback, it works fine, Please check if you are missing anything in your implementation

public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        try {
            Log.d(TAG, "surfaceCreated(), holder"+holder.toString());
            mCamera = null;
            mCamera = Camera.open();
            Log.d(TAG, "surfaceCreated(), mCamera="+mCamera);
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(holder);
            Camera.Parameters params= mCamera.getParameters();
            params.set("jpeg-quality", 72);
            params.set("rotation", 90);
            params.set("orientation", "portrait");
            params.setPictureFormat(PixelFormat.JPEG);
                    mCamera.setParameters(params);
            createZoomlayout();

        } catch (Exception e) {
            Toast.makeText(CameraInterface.this,
                    " surfaceCreated " + e.getMessage(), Toast.LENGTH_LONG)
                    .show();
            e.printStackTrace();
        }
    }

Upvotes: 3

Anoop
Anoop

Reputation: 993

try this snippet

camera.setDisplayOrientation(90)

Upvotes: 2

Related Questions