Reputation: 39
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
Reputation: 134
in your manifest file add this line in your activity: android:screenOrientation="landscape"
Upvotes: -1
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