【问题标题】:Android: Jpeg saved from camera looks corruptedAndroid:从相机保存的 Jpeg 看起来已损坏
【发布时间】:2011-05-02 16:46:22
【问题描述】:

我正在编写一个 Android 应用程序,当用户单击按钮时,它会保存来自相机的 JPEG 快照。不幸的是,当我查看 JPEG 文件时,我保存的代码看起来已损坏。这似乎是由我对 parameters.setPreviewSize 的调用引起的(请参见下面的代码 sn-p) - 如果我删除它,那么图像保存得很好;但是没有它我无法设置预览大小,并且 setDisplayOrientation 没有它似乎也没有效果。

我的应用程序面向 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 {
            }
        }
    }
};

【问题讨论】:

  • 我也遇到过,但仅适用于 HTC Desire HD。 jpeg 在三星 Galaxy S 和模拟器上保存得很好。
  • @jA_cOp - 谢谢你,至少我知道错的不是我! Android 源代码中的相机应用运行良好,因此我将对其进行研究并找出其中的差异。
  • 问题解决了吗?我遇到了同样的问题,只有 HTC Desire HD
  • @Ikky - 我还没有机会回到这个项目,我会在这里更新
  • 如果 setPreviewSize 不是必需的,请尝试删除对我有用的 parameters.setPreviewSize。

标签: android android-camera


【解决方案1】:

另一种解决方法是匹配预览和图片尺寸之间的纵横比(即 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 一样好(如果您不介意图像失真 ;-)

【讨论】:

  • 我可以在我的 HTC Desire S 设备上确认这一点。顺便说一句,在此设备上的本机相机应用程序中,您可以在设置中定义纵横比(4:3 或 5:3)和分辨率。可用分辨率列表取决于纵横比,因为它们似乎需要匹配。
【解决方案2】:

我假设您正在使用浮动的 getBestPreviewSize(w,h) 方法的通用实现,您可以在其中循环通过不同的 getSupportedPreviewSizes() 以找到最佳匹配。虽然我不确定它为什么会导致图像失真,但我发现使用 getBestPreviewSize 方法的输出调用 parameters.setPreviewSize(size.width, size.height) 方法是导致问题的原因宏达愿望。我还验证了通过注释掉它,图像失真问题就消失了。

【讨论】:

  • 我的应用也有类似的问题并删除了 setPreviewSize,一些用户 (Desire S) 仍然遇到问题。所以这不仅仅是与这部分代码有关的事情。我看过很多关于这个的帖子,真的很喜欢有人可以解释为什么图片看起来像这样的细节
  • 很好的回应!在过去的几个小时里,我一直在寻找这一点,同时在转换为 YUV 时从 onFramePreview 获得的失真图像苦苦挣扎。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2023-03-19
  • 2016-05-24
  • 1970-01-01
相关资源
最近更新 更多