2014-09-23 24 views
0

我有一個作爲FrameLayout的活動,用作片段的容器視圖。這個片段包含一個SurfaceView,在其SurfaceHolder中顯示相機預覽。SurfaceView上的圖片會產生小圖片文件和錯誤的方向

點擊/點擊相機的SurfaceView takePicture時,會調用PhotoHandler回調函數,該回調函數實現了PictureCallback。重寫的方法onPictureTaken接收包含圖像數據的字節數組,該數據使用FileOutputStream存儲。

我將活動限制爲縱向(在清單中),並使用了方法setCameraDisplayOrientation(在stackoverflow上找到),該方法也將以縱向方向顯示相機預覽。

一切工作得很好...除了兩件事情:

  1. 生成的圖像文件非常小(約40KB)
  2. 生成的圖像文件似乎是旋轉90度向左

所以我的問題是

我可以提高圖像質量(以全尺寸)?

我可以確保生成的圖像文件具有縱向方向嗎?

以下是我的一些代碼

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="org.xxxxxxxxxxxxxxx" > 

    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <uses-feature android:name="android.hardware.camera" /> 
    <uses-feature android:name="android.hardware.camera.autofocus" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".xxxxxxxxxx" 
      android:label="@string/app_name" 
      android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

onPictureTaken

@Override 
public void onPictureTaken(byte[] data, Camera camera) { 

    File pictureFileDir = getDir(); 

    if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) { 

     Toast.makeText(context, "Can't create directory to save image.", 
       Toast.LENGTH_LONG).show(); 
     return; 

    } 

    String filename = pictureFileDir.getPath() + File.separator + photoFile; 

    File pictureFile = new File(filename); 

    try { 
     FileOutputStream fos = new FileOutputStream(pictureFile); 
     fos.write(data); 
     fos.close(); 
    } catch (Exception error) { 
     Toast.makeText(context, "Image could not be saved.", 
       Toast.LENGTH_LONG).show(); 
    } 
} 

請讓我知道,如果你有什麼事?

編輯:我找到了尺寸問題的解決方案(請參閱下面的答案)。但我仍然有旋轉的結果圖像文件的問題。經過大量測試後,我發現即使以縱向模式拍攝,圖像始終以橫向格式存儲。也許在文件中的一些EXIF信息標記爲肖像...我繼續測試,但你仍然可以幫助我在這裏:-)

編輯2:我的關於Exif信息的想法似乎是正確的起點。標準方向(至少在手機的相機上)似乎是「向左旋轉90度的風景」。至少,這是圖像文件的Exif信息告訴我的:圖像的第0行在頂部,第0列在左邊(TAG_ORIENTATION是1)

即使我清楚地以縱向拍照模式,Exif信息並不反映這一點。它似乎「認爲」圖像處於橫向模式,所以我必須將它向右旋轉90度以顯示它。這對我來說似乎是錯誤的...我如何確保圖像中的Exif信息反映了相機/應用程序的方向? (TAG_ORIENTATION顯然應該是6)

不要誤解我的意思:我仍然需要向右旋轉90度,但是Exif信息的TAG_ORIENTATION應該告訴我這樣做。目前,我必須依靠我的知識來了解照片是如何拍攝的。

參見: Android: Bitmaps loaded from gallery are rotated in ImageView

和: http://sylvana.net/jpegcrop/exif_orientation.html

EDIT3:解...見下文

回答

3

好吧,我至少能夠解決的大小問題。我根據手機/相機功能

Camera.Parameters params = camera.getParameters(); 

List<Camera.Size> sizeList = params.getSupportedPictureSizes(); 
int chosenSize = Helper.getPictureSizeIndexForHeight(sizeList, 800); 
params.setPictureSize(sizeList.get(chosenSize).width, sizeList.get(chosenSize).height); 

camera.setParameters(params); 

和輔助方法,幫助我選擇的最小高度greather比第二個參數圖片尺寸發現PictureSize參數與我可以設置想要的結果圖像尺寸(或者可用的最大尺寸)

public static int getPictureSizeIndexForHeight(List<Camera.Size> sizeList, int height) { 
    int chosenHeight = -1; 
    for(int i=0; i<sizeList.size(); i++) { 
     if(sizeList.get(i).height < height) { 
      chosenHeight = i-1; 
      if(chosenHeight==-1) 
       chosenHeight = 0; 
      break; 
     } 
    } 
    return chosenHeight; 
} 

這工作,但我窗臺有旋轉的圖像結果文件的問題

編輯:我發現我需要設置所謂另一個參數取決於手機方向和用戶界面方向。在這種情況下,手機將設置正確的exif信息,以便在縱向拍攝時圖像不會以橫向顯示。我不需要再旋轉,圖像也能正確顯示在相冊中。

public static void setRotationParameter(Activity activity, int cameraId, Camera.Parameters param) { 

    android.hardware.Camera.CameraInfo info = 
      new android.hardware.Camera.CameraInfo(); 
    android.hardware.Camera.getCameraInfo(cameraId, info); 

    int rotation = activity.getWindowManager().getDefaultDisplay() 
      .getRotation(); 
    rotation = (rotation + 45)/90 * 90; 

    int toRotate = (info.orientation + rotation) % 360; 

    param.setRotation(toRotate); 
} 
+0

你幫我這個請http://stackoverflow.com/questions/39061991/onpicturetaken-byte-small-size-in-some-device – 2016-08-21 11:52:05