Android: сохраненный Jpeg с камеры выглядит испорченным - PullRequest
3 голосов
/ 02 мая 2011

Я пишу приложение для Android, которое сохраняет снимок JPEG с камеры, когда пользователь нажимает кнопку.К сожалению, когда я смотрю на файл JPEG, мой код сохранения выглядит поврежденным.Похоже, что это вызвано моим вызовом parameters.setPreviewSize (см. Фрагмент кода ниже) - если я уберу это, то изображение сохранится нормально;однако без него я не могу установить размер предварительного просмотра, и 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 {
            }
        }
    }
};

Ответы [ 2 ]

4 голосов
/ 14 октября 2011

Другим обходным решением является сопоставление соотношения сторон между предварительным просмотром и размерами изображения (например, 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 (если вы не возражаете против искаженных изображений; -)

2 голосов
/ 28 мая 2011

Я предполагаю, что вы используете общую реализацию метода getBestPreviewSize (w, h), который перемещается по кругу, где вы перебираете различные getSupportedPreviewSizes (), чтобы найти лучшее соответствие.Хотя я не уверен в том, почему это приводит к искажению изображений, я обнаружил, что вызов метода parameters.setPreviewSize (size.width, size.height) с выводом метода getBestPreviewSize является причиной проблемыHTC Desire.Я также подтвердил, что, комментируя это, проблема искаженного изображения исчезает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...