2013-07-22 71 views
0

我開發的自定義相機應用程序始終將圖像旋轉90度,相機的屏幕視圖扭曲且逆時針旋轉90度,但在保存圖像時,就好像我用手機拍了照片,當我拿着它的肖像時,我的手機向左轉90度,它拍攝了風景照片。 這裏是相機活動的代碼,我能做些什麼來旋轉我的相機的屏幕視圖?相機應用程序將圖像旋轉90度

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; 
    } 
} 
} 

(評論是在法國偶爾,就像我跟一個法國同事的工作,雖然我不會說法語了。)

回答

3

這是我的執行surfaceCreated方法SurfaceHolder.Callback,它工作正常,請檢查你是否遺漏了你的任何東西

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(); 
     } 
    } 
+0

謝謝,我剛剛複製並粘貼了一小段: Camera.Parameters params = camera.getParameters(); params.set(「jpeg-quality」,72); params.set(「rotation」,90); params.set(「orientation」,「portrait」); params.setPictureFormat(PixelFormat.JPEG); camera.setParameters(params); 我也需要camera.setDisplayOrientation(90);來自Anoopss Golden,謝謝 – simfrek

+0

很高興看到這適合你。快樂編碼。 – AAnkit

+0

謝謝,工作正常 – sandeepmaaram

2

試試這個片斷

camera.setDisplayOrientation(90) 
+0

我使用的是surfaceCamera – simfrek

+0

多數民衆贊成罰款...你嘗試過這個code.It將與surfaceHolder –

+0

工作是它適用於顯示器,但它保存的照片仍然不亮,同時旋轉手機時,圖像在水平和垂直方向之間稍微拉伸一半,圖像本身也有點拉長/壓扁,現在我看起來更接近 – simfrek

-1

在你的清單文件在你的活動中加入這一行: 機器人:screenOrientation =「風景」