2011-05-02 31 views
2

我正在編寫一個Android應用程序,當用戶單擊按鈕時,可以從相機保存JPEG快照。不幸的是,當我看着JPEG文件時,我的代碼看起來已經損壞。它似乎是由我調用parameters.setPreviewSize(請參閱下面的代碼片段)引起的 - 如果我刪除它,則圖像可以很好地保存;但是沒有它,我無法設置預覽大小,並且setDisplayOrientation在沒有它的情況下似乎也沒有效果。Android:從相機保存的Jpeg看起來損壞

我的應用程序針對的API級別8(Android 2.2),我正在調試HTC Desire HD。不太確定我在這裏做錯了什麼......任何幫助將非常感激!

乾杯, 斯科蒂

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // Now that the size is known, set up the camera parameters and begin 
    // the preview. 
    Camera.Parameters parameters = mCamera.getParameters();   
    Camera.Size size = getBestPreviewSize(w,h); 

    // This next call is required in order for preview size to be set and 
    // setDisplayOrientation to take effect... 
    // Unfortunately it's also causing JPEG to be created wrong 
    parameters.setPreviewSize(size.width, size.height); 

    parameters.setPictureFormat(ImageFormat.JPEG); 
    mCamera.setParameters(parameters); 
    mCamera.setDisplayOrientation(90); 

    mCamera.startPreview(); 

} 

// This is the snapshot button event handler 
public void onSnapshotButtonClick(View target) { 
    //void android.hardware.Camera.takePicture(ShutterCallback shutter, 
    //        PictureCallback raw, PictureCallback jpeg) 
    mPreview.mCamera.takePicture(null, null, mPictureCallback); 
} 


// This saves the camera snapshot as a JPEG file on the SD card 
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { 
    public void onPictureTaken(byte[] imageData, Camera c) { 

     if (imageData != null) { 
      FileOutputStream outStream = null; 
      try { 
       String myJpgPath = String.format(
         "/sdcard/%d.jpg", System.currentTimeMillis()); 

       outStream = new FileOutputStream(myJpgPath); 
       outStream.write(imageData); 
       outStream.close(); 
       Log.d("TestApp", "onPictureTaken - wrote bytes: " 
         + imageData.length); 

       c.startPreview(); 
       Toast.makeText(getApplicationContext(), String.format("%s written", myJpgPath), Toast.LENGTH_SHORT).show(); 

      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
      } 
     } 
    } 
}; 
+1

也適用於我,但只適用於HTC Desire HD。 jpeg在Samsung Galaxy S和模擬器上可以很好地保存。 – 2011-05-14 22:11:42

+0

@jA_cOp - 感謝你,至少我知道這不是我錯了! Android源代碼中的相機應用程序工作正常,因此我將對此進行研究並找出差異。 – Scottie 2011-05-16 10:14:06

+0

你解決了這個問題嗎?我碰到同樣的問題,只有HTC Desire HD – Ikky 2011-06-07 13:15:28

回答

2

我假設你正在使用的getBestPreviewSize的共同實現(W,H)方法是浮動的約,在那裏你通過不同的getSupportedPreviewSizes週期()找到最佳匹配。雖然我不確定它爲什麼會導致圖像失真,但我發現使用getBestPreviewSize方法的輸出調用parameters.setPreviewSize(size.width,size.height)方法是導致問題的原因HTC Desire。我也證實,通過評論它,扭曲的形象問題消失。

+0

我有一個與我的應用程序類似的問題,並刪除了setPreviewSize,一些用戶(慾望S)仍然有問題。所以這不僅僅與這部分代碼有關。我已經看到了很多關於此的帖子,真的很喜歡有人可以解釋爲什麼圖片出現這樣的細節 – 2011-07-08 13:28:30

+0

偉大的迴應!在轉換爲YUV時,我一直在尋找最近幾個小時的時間,同時努力處理來自onFramePreview的扭曲圖像。非常感謝 ! – Muzikant 2012-03-10 19:54:51

4

另一個解決方法是匹配預覽和圖片大小(即setPreviewSize(w1,h1); setPictureSize(w2,h2))與w1/h1〜w2/h2(小差異似乎正常)之間的長寬比。例如。對於Desire HD S w1 = 800,h1 = 480,w2 = 2592,h2 = 1552,以及w1 = 960,h1 = 720,h2 = 2592,h2 = 1952(如果你不介意扭曲圖像;-)

+0

我可以在我的HTC Desire S設備上確認這一點。順便說一下,在該設備上的本機相機應用程序中,您可以在設置中定義寬高比(4:3或5:3)和分辨率。可用分辨率列表取決於長寬比,因爲它們似乎需要匹配。 – 2014-04-25 08:30:00