Функция startPreview работает медленно, есть ли обход? - PullRequest
8 голосов
/ 09 сентября 2011

Проблема:

Я делаю приложение на Android, которое требует быстрой реакции от камеры во время съемки изображений, я заметил медленное поведение приложения, после измерения времени я заметил, что функция startPreview () отвечает за проблему.

Предварительный просмотр кода:

Это необходимая часть кода (связана с проблемой).

PreviewGoogle Class (пользовательский предварительный просмотр): В начале приложения вызывается SurfaceChanged, я установил некоторые параметры камеры, затем назвал startPreview

public class PreviewGoogle extends ViewGroup implements SurfaceHolder.Callback {
    private final String TAG = "myapp1";
    Camera mCamera;

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

            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
            parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
            parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
            parameters.setJpegQuality(100);
            parameters.setPictureSize(Globals.CAMERA_WIDTH, Globals.CAMERA_HEIGHT);

            requestLayout();
            mCamera.setParameters(parameters);

            long before = System.currentTimeMillis();
            mCamera.startPreview();
            long after = System.currentTimeMillis();

            Log.d(TAG, "PreviewGoogle, surfaceChanged: startPreview took " + (after - before) + " ms");
        }
        catch (Exception e) {
            Log.d(TAG, "PreviewGoogle, surfaceChanged: " + e.getMessage());
        }
    }
}

Класс PhotoShootActivity: В этом классе я вызвал startPreview для rawImageCallback, потому что я использую BitmapFactory в jpegCallback (не обязательно)

public class PhotoShootActivity extends Activity
{
    private static final String TAG = "myapp1";
    PreviewGoogle preview;

    // Handles data for raw picture
    PictureCallback rawCallback = new PictureCallback()
    {
        public void onPictureTaken(byte[] data, Camera camera)
        {
            try
            {
                long before = System.currentTimeMillis();
                preview.getCamera().startPreview();
                long after = System.currentTimeMillis();

                Log.d(PhotoShootActivity.TAG, "PhotoShootActivity, rawCallback: preview started in " + (after - before) + " ms");
            }
            catch(Exception e)
            {
                Log.e(TAG, "PhotoShootActivity, rawCallback: " + e.getMessage());
            }
        }
    };
}

Номера таймеров были такими:

09-09 10:58:42.336: DEBUG/myapp1(21958): PhotoShootActivity, onCreate
**09-09 10:58:44.396: DEBUG/myapp1(21958): PreviewGoogle, surfaceChanged: startPreview took 1457 ms**
09-09 10:58:48.438: DEBUG/myapp1(21958): PhotoShootActivity, buttonCapture: Picture taken in 65ms
09-09 10:58:48.496: DEBUG/myapp1(21958): PhotoShootActivity, shutterCallback: Empty
**09-09 10:58:49.790: DEBUG/myapp1(21958): PhotoShootActivity, rawCallback: preview started in 662 ms**

Первый startPreview занял ~ 1500 мс, а второй - 662 мс !!!

Искомое решение:

Вопрос, который я ищу, не полный код (просто напишите мне :)), я подумал, что могу что-то упустить в предварительном просмотре, и я подумал об использовании потоков в этом случае, но я не знакомы с Android-SDK еще (я начал с программирования Android 4 дня назад)

Привет ...

1 Ответ

0 голосов
/ 22 января 2014

Из документации на андроид:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

startPreview()

Начинает захват и отрисовку рамок предварительного просмотра на экране. Предварительный просмотр фактически не начнется, пока поверхность не будет снабжена setPreviewDisplay(SurfaceHolder) или setPreviewTexture(SurfaceTexture).

Если были вызваны setPreviewCallback(Camera.PreviewCallback), setOneShotPreviewCallback(Camera.PreviewCallback), или setPreviewCallbackWithBuffer(Camera.PreviewCallback), onPreviewFrame(byte[], Camera) будет вызвано, когда станут доступны данные предварительного просмотра.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Итак, в своем комментарии вы сказали, что решили использовать onPreviewFrame(byte[], Camera), как вы можете видеть в документах, в нем говорится, что он вызывается только тогда, когда становятся доступны данные предварительного просмотра, что занимает некоторое время. Попробуйте добавить первый вариант, предоставив камере текстуру или экран предварительного просмотра.

Т.е. В вашем surfaceChanged(SurfaceHolder holder, int format, int w, int h) методе:

mCamera.setPreviewDisplay(holder);

Посмотрите, имеет ли это значение.

...