Android:从相机保存的Jpeg看起来损坏

问题描述:

我正在编写一个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

我假设你正在使用的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

另一个解决方法是匹配预览和图片大小(即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