2013-01-09 140 views
1

我已經定義了一個自定義相機視圖拍照。 我得到的問題是如果照片是用「肖像」拍攝的相機拍攝的,則圖像旋轉90度。如果我在「風景」模式下拍攝照片,它會變得正確。android自定義相機方向問題

我的代碼如下。我嘗試了幾個解決方案,如Android - Camera preview is sideways 但它並沒有解決我的問題。

請給我一些指導。 謝謝。

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


} 
+0

我不知道它適用於此,因爲我不打算使用意圖打開相機。同時我正在嘗試做類似的 – png

+0

它不會解決我的問題。存儲在圖庫中的圖像具有正確的方向。這不是這裏的情況 – png

+0

@Preetha你的問題解決了嗎? – Riser

回答

0

當你轉換byte[]onPictureTake()一個Bitmap,你扔掉包括字節數組中的方位信息。如果要保存方向信息,則應直接將字節寫入File