2013-02-13 1 views
4

Итак, я работаю над чем-то вроде приложения для камеры. Он рисует предварительный просмотр в реальном времени на естественной текстуре OpenGL. Если нажата кнопка, неподвижное изображение захватывается (возможно, с более высоким разрешением, чем предварительный просмотр в реальном времени) в его исходной форме.Камера для Android, одновременный предварительный просмотр и Rake TakePicture

Вот общая схема моего кода. Для ясности я не показываю менее значимые фрагменты. Это упрощенная ситуация, когда разрешения предварительного просмотра и все еще ограничены.

void Setup(Activity a) { 

    // .. snip .. 

    mSurfaceView = new SurfaceView(a); 
    mSurfaceView.getHolder().addCallback(this); 
    //put the surface off-screen 
    AbsoluteLayout.LayoutParams alp = new AbsoluteLayout.LayoutParams(8, 8, -8, -8); 
    a.addContentView(mSurfaceView, alp); //need this, otherwise surface is not created 

    mCamera = Camera.open(miCameraId); 
    mCamera.setPreviewCallbackWithBuffer(this); 

    ConfigureCameraDefaults(640,480); 
} 

// -------------------------------------------------------------------- // 

void ConfigureCameraDefaults(int iX, int iY) { 
    Camera.Parameters oParameters=mCamera.getParameters(); 

    oParameters.setPreviewFormat(ImageFormat.NV21); 
    oParameters.setPictureFormat(ImageFormat.NV21); 
    oParameters.setPreviewSize(iX, iY); // for live preview 
    oParameters.setPictureSize(iX, iY); // for still capture 

    int bpp = ImageFormat.getBitsPerPixel(ImageFormat.NV21); 
    int iBufSize = (int) (iX*iY*((float)bpp/8)); 
    mBuffer = new byte[iBufSize]; 
    mCamera.addCallbackBuffer(mBuffer); 

    try { 
     mCamera.setParameters(oParameters); 
    } catch (Exception e) { 
     // .. snip .. 
    } 
} 

void startPreview() { 
    mCamera.startPreview(); 
} 

void stopPreview() { 
    mCamera.stopPreview(); 
} 

void takePicture() { 
    mCamera.takePicture(null, this, null, null); //2nd is the raw callback 
} 

// -------------------------------------------------------------------- // 

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    // -- at this point the buffer is in a safe state, until it is added again 
    onPreviewFrame_native(data); 

    // -- make buffer writable again 
    mCamera.addCallbackBuffer(mBuffer); 
} 

@Override 
public void onPictureTaken(byte[] data, Camera camera) { 
    onStillCapture_native(data); 
    mCamera.startPreview(); //otherwise preview will stop 
} 

Хорошо, теперь вопросы. Когда takePicture() не вызывается, все функции в соответствии с планом. Рамки предварительного просмотра прибывают, они обрабатываются, буфер переупорядочивается. Однако, если I startPreview(), то сделать takePicture(), обратный вызов изображения получает нулевой массив данных. Каждый раз. Google Docs есть это, чтобы сказать о takePicture():

The raw callback occurs when the raw image data is available (NOTE: the data will be null if there is no raw image callback buffer available or the raw image callback buffer is not large enough to hold the raw image).

Это не совсем ясно для меня, как:

  1. Там нет функции установить буфер стоп-кадра, только подборка ФОТО кадров
  2. Даже если тот же буфер используется как для кеш-кадров, так и для предварительных кадров, у меня есть буфер в очереди.
  3. Добавление второго буфера (идентичный буфер предварительного просмотра) специально для еще шапки не имеет абсолютно никакого эффекта
  4. Предварительный просмотр должен быть запущен для того, чтобы takePicture() быть действительным вызова.

Я пропустил что-то очевидное? Или нам не разрешено получать необработанные кадры из видео и все еще в одно и то же время? В документах об этом ничего нет. Я также посмотрел на источник камеры, но безрезультатно.

Любая помощь была бы принята с благодарностью.

PS. Я попытался использовать другой формат цвета для неподвижного, снятия обратного вызова предварительного просмотра перед тем, как сделать снимок, добавив второй буфер, запросив второй буфер, установив держатель поверхности для ввода типа и некоторые другие вещи, которые я не могу вспомнить на момент. Ничего не изменилось.

+0

Вы нашли решение? –

ответ

0

Кажется, что нет никакого способа получить необработанное изображение. Метод addCallbackBuffer используется только для обратных вызовов предварительного просмотра. Существует еще один метод addRawImageCallbackBuffer, который должен делать то, что вы хотите. Он общедоступен, но не экспортируется, поэтому вы не можете его напрямую называть. Вы можете назвать это так:

try { 
     final Method addRawImageCallbackBuffer = 
       camera0.getClass() 
         .getDeclaredMethod("addRawImageCallbackBuffer", 
              byte[].class); 
     addRawImageCallbackBuffer.invoke(camera0, new byte[100000000]); 
    } catch (Exception e) { 
     Log.e("RNG", "Error", e); 
    } 

но на моем Nexus 5, все равно возвращается null на обратный вызов, так что я думаю, что это просто не поддерживается.