6

I have a question regarding the preview callbacks with Android 4.0.x. I set up a camera, create a surface to display camera image on previewCallback-event. Everything works fine.

But with Android 4.0.x neither onPreviewCallback is called nor onPreviewCallbackWithBuffer. Is there a workaround for this issue?

I want to take a screen shot and do not want to use the takePicture()-way because it freezes the live image for a short-time.

Parth Bhatt
  • 19,381
  • 28
  • 133
  • 216
tomcat.exe
  • 95
  • 1
  • 6
  • You see the live preview in your surface view, don't you? And how exactly do you call setPreviewCallback()? – Alex Cohn Dec 11 '12 at 15:12
  • Live Preview is working. Also the callbacks works perfect on other androids than 4.0.x. `mCamera.setPreviewCallback(new Camera.PreviewCallback() { public void onPreviewFrame(byte[] data, Camera camera) { ... //CODE } });` – tomcat.exe Dec 11 '12 at 15:30
  • 1
    Maybe, mCamera is not ready when you call setPreviewCallback()? Maybe, you set camera parameters incorrectly? Is there anything camera-related in the logcat? – Alex Cohn Dec 11 '12 at 16:01
  • Logcat shows nothing unusual. Camera initializes complete.Tests with takePicture-Callback worked fine. Tried also to set `setOneShotPreviewCallback(Camera.PreviewCallback)`. Seems events are just not called... – tomcat.exe Dec 11 '12 at 16:11
  • Which device this is? Have you tried to change the default resolution, pixel format? – Alex Cohn Dec 12 '12 at 07:02
  • Test devices are pretty low budget Android-Tablets (1. Odys Neo X7 and 2. Ainol Novo 7). All testing was done with cameras default resolution and pixel format. Will test callbacks with changed pixel format and/or resolution today... – tomcat.exe Dec 12 '12 at 08:42

3 Answers3

7

You must to call setPreviewCallback in surfaceChanged method, not only in surfaceCreated.

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    if (mHolder.getSurface() == null){
      return;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e){
      // ignore: tried to stop a non-existent preview
    }

    try {
        mCamera.setPreviewCallback(this);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

    } catch (Exception e){
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}
Neonigma
  • 1,825
  • 17
  • 20
2

you can call setOneShotPreviewCallback

mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    Camera.Parameters parameters = camera.getParameters();
                    int format = parameters.getPreviewFormat();
                    //YUV formats require more conversion
                    if (format == ImageFormat.NV21 || format == ImageFormat.YUY2 || format == ImageFormat.NV16) {
                        int w = parameters.getPreviewSize().width;
                        int h = parameters.getPreviewSize().height;
                        // Get the YuV image
                        YuvImage yuv_image = new YuvImage(data, format, w, h, null);
                        // Convert YuV to Jpeg
                        Rect rect = new Rect(0, 0, w, h);
                        ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
                        yuv_image.compressToJpeg(rect, 100, output_stream);
                        byte[] byt = output_stream.toByteArray();
                        FileOutputStream outStream = null;
                        try {
                            // Write to SD Card
                            File file = createFileInSDCard(FOLDER_PATH, "Image_"+System.currentTimeMillis()+".jpg");
                            //Uri uriSavedImage = Uri.fromFile(file);
                            outStream = new FileOutputStream(file);
                            outStream.write(byt);
                            outStream.close();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                        }
                    }
                }
ROHIT PARMAR
  • 901
  • 15
  • 26
0

I had also a similar issue. I initialized PreviewCallbackWithBuffet before camera's ready. To solve the problem, I have used below code:

_camera.addCallbackBuffer(createPreviewBuffer(new Size(width, height)));
                    _camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
                        @Override
                        public void onPreviewFrame(byte[] bytes, Camera camera) {
                            processingRunnable.setNextFrame(bytes, camera))
                        }
                    });
                    _camera.startPreview();

Hope it helps