如何使相机可以使用连拍模式

发布于 2024-11-27 10:22:53 字数 7182 浏览 0 评论 0原文

我正在尝试构建一个带有相机连拍模式的小型照片应用程序。主要思想是每 0.3 秒拍摄一张照片并将照片存储在数组中,直到拍摄最后一张照片。应指定要​​拍摄的照片数量。

我只能每2秒拍一张照片。作为最短间隔。然后,当将图片写入存储时,应用程序就会崩溃。

有人知道如何实现这个吗?这是我的代码:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;

public class CamaeaView extends Activity implements SurfaceHolder.Callback, OnClickListener {

    static final int FOTO_MODE = 1;
    private static final String TAG = "Test";
    Camera mCamera;
    boolean mPreviewRunning = false;
    private Context mContext = this;
    ArrayList<Object> listImage = null;
    public static ArrayList<Object> List1[];

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        Log.e(TAG, "onCreate");

        @SuppressWarnings("unused")
        Bundle extras = getIntent().getExtras();

        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceView.setOnClickListener(this);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] imageData, Camera c) {
            Log.d("Start: ","Imagelist");

            Intent mIntent = new Intent();
            listImage.add(StoreByteImage(imageData));
            SaveImage(listImage);
            mCamera.startPreview();

            setResult(FOTO_MODE, mIntent);
            finish();

        }
    };

    protected void onResume() {
        Log.d(TAG, "onResume");
        super.onResume();
    }

    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    protected void onStop() {
        Log.e(TAG, "onStop");
        super.onStop();
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated");
        mCamera = Camera.open();

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Log.d(TAG, "surfaceChanged");

        // XXX stopPreview() will crash if preview is not running
        if (mPreviewRunning) {
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(w, h);
        p.setPictureSize(1024, 768);
        p.getSupportedPictureFormats();
        p.setPictureFormat(PixelFormat.JPEG);
        mCamera.setParameters(p);
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mCamera.startPreview();
        mPreviewRunning = true;
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.e(TAG, "surfaceDestroyed");
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();
    }

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    public void onClick(View arg0) {
        int i = 0;
        while (i < 4) {

            mCamera.takePicture(null, mPictureCallback, mPictureCallback);
            i = i + 1;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static Object StoreByteImage(byte[] imageData) {

        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
            ObjectInputStream objImageData = new ObjectInputStream(bis);
            obj = objImageData.readObject();

        } catch (IOException ex) {
            // TODO: Handle the exception
        } catch (ClassNotFoundException ex) {
            // TODO: Handle the exception
        }
        return obj;

    }

    public static Object createImagesArray(byte[] imageData) {

        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
            ObjectInputStream objImageData = new ObjectInputStream(bis);
            obj = objImageData.readObject();

        } catch (IOException ex) {
            // TODO: Handle the exception
        } catch (ClassNotFoundException ex) {
            // TODO: Handle the exception
        }
        return obj;

    }

    public static boolean SaveImage(List<Object> listImage) {

        FileOutputStream outStream = null;
        Log.d("ListSize: ", Integer.toString(listImage.size()));
        Iterator<Object> itList = listImage.iterator();
        byte[] imageBytes = null;
        while (itList.hasNext()) {

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(listImage);
                oos.flush();
                oos.close();
                bos.close();
                imageBytes = bos.toByteArray();
            } catch (IOException ex) {
                // TODO: Handle the exception
            }

            try {
                // Write to SD Card
                outStream = new FileOutputStream(String.format(
                        "/sdcard/DCIM/%d.jpg", System.currentTimeMillis())); // <9>
                outStream.write(imageBytes);
                outStream.close();

            } catch (FileNotFoundException e) { // <10>
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
        Log.d(TAG, "onPictureTaken - jpeg");

        return true;
    }

}

评论中的错误:

ERROR/MemoryHeapBase(1382): error opening /dev/pmem_camera: No such file or directory 
ERROR/QualcommCameraHardware(1382): failed to construct master heap for pmem pool /dev/pmem_camera 
ERROR/QualcommCameraHardware(1382): initRaw X failed with pmem_camera, trying with pmem_adsp

I am trying to build a small photo app with a burst mode for camera. The main idea is to shoot a picture every 0,3sec and to store the pictures in an Array until the last picture is taken. The number of pictures to shoot should specified.

I can only shoot a picture every 2sec. as shortest interval. Then, when the pictures should be written to storage, the applications chrashes.

Does someone know how to implement this? Here is my code:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;

public class CamaeaView extends Activity implements SurfaceHolder.Callback, OnClickListener {

    static final int FOTO_MODE = 1;
    private static final String TAG = "Test";
    Camera mCamera;
    boolean mPreviewRunning = false;
    private Context mContext = this;
    ArrayList<Object> listImage = null;
    public static ArrayList<Object> List1[];

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        Log.e(TAG, "onCreate");

        @SuppressWarnings("unused")
        Bundle extras = getIntent().getExtras();

        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceView.setOnClickListener(this);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] imageData, Camera c) {
            Log.d("Start: ","Imagelist");

            Intent mIntent = new Intent();
            listImage.add(StoreByteImage(imageData));
            SaveImage(listImage);
            mCamera.startPreview();

            setResult(FOTO_MODE, mIntent);
            finish();

        }
    };

    protected void onResume() {
        Log.d(TAG, "onResume");
        super.onResume();
    }

    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    protected void onStop() {
        Log.e(TAG, "onStop");
        super.onStop();
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated");
        mCamera = Camera.open();

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Log.d(TAG, "surfaceChanged");

        // XXX stopPreview() will crash if preview is not running
        if (mPreviewRunning) {
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(w, h);
        p.setPictureSize(1024, 768);
        p.getSupportedPictureFormats();
        p.setPictureFormat(PixelFormat.JPEG);
        mCamera.setParameters(p);
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mCamera.startPreview();
        mPreviewRunning = true;
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.e(TAG, "surfaceDestroyed");
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();
    }

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    public void onClick(View arg0) {
        int i = 0;
        while (i < 4) {

            mCamera.takePicture(null, mPictureCallback, mPictureCallback);
            i = i + 1;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static Object StoreByteImage(byte[] imageData) {

        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
            ObjectInputStream objImageData = new ObjectInputStream(bis);
            obj = objImageData.readObject();

        } catch (IOException ex) {
            // TODO: Handle the exception
        } catch (ClassNotFoundException ex) {
            // TODO: Handle the exception
        }
        return obj;

    }

    public static Object createImagesArray(byte[] imageData) {

        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
            ObjectInputStream objImageData = new ObjectInputStream(bis);
            obj = objImageData.readObject();

        } catch (IOException ex) {
            // TODO: Handle the exception
        } catch (ClassNotFoundException ex) {
            // TODO: Handle the exception
        }
        return obj;

    }

    public static boolean SaveImage(List<Object> listImage) {

        FileOutputStream outStream = null;
        Log.d("ListSize: ", Integer.toString(listImage.size()));
        Iterator<Object> itList = listImage.iterator();
        byte[] imageBytes = null;
        while (itList.hasNext()) {

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(listImage);
                oos.flush();
                oos.close();
                bos.close();
                imageBytes = bos.toByteArray();
            } catch (IOException ex) {
                // TODO: Handle the exception
            }

            try {
                // Write to SD Card
                outStream = new FileOutputStream(String.format(
                        "/sdcard/DCIM/%d.jpg", System.currentTimeMillis())); // <9>
                outStream.write(imageBytes);
                outStream.close();

            } catch (FileNotFoundException e) { // <10>
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
        Log.d(TAG, "onPictureTaken - jpeg");

        return true;
    }

}

Error from the comments:

ERROR/MemoryHeapBase(1382): error opening /dev/pmem_camera: No such file or directory 
ERROR/QualcommCameraHardware(1382): failed to construct master heap for pmem pool /dev/pmem_camera 
ERROR/QualcommCameraHardware(1382): initRaw X failed with pmem_camera, trying with pmem_adsp

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘虞初梦 2024-12-04 10:22:53

AFAIK,在第一张照片完成之前,您无法拍摄另一张照片。消除 for 循环和 Thread.sleep()。在mPictureCallback中拍摄下一张照片。

主要思想是每 0.3 秒拍摄一张照片并将照片存储在数组中,直到拍摄最后一张照片。

“0.3秒”目标比大多数设备处理图像的速度要快,并且您可能没有足够的堆空间来容纳图像数组。我怀疑您必须将每个图像通过 AsyncTask 传入磁盘,这样您就可以释放堆空间,同时又不会占用主应用程序线程。

AFAIK, you cannot take another picture until the first one is complete. Eliminate your for loop and Thread.sleep(). Take the next picture in mPictureCallback.

The main idea is to shoot a picture every 0,3sec and to store the pictures in an Array until the last picture is taken.

The "0,3sec" objective is faster than most devices can process an image, and you may not have enough heap space for your array of images. I suspect that you will have to write each image out to disk as it comes in via an AsyncTask, so you can free up the heap space while also not tying up the main application thread.

前事休说 2024-12-04 10:22:53

您可以尝试在预分配的字节数组中捕获后续预览帧。
请参阅以下方法:

http: //developer.android.com/reference/android/hardware/Camera.html#addCallbackBuffer(byte[])
http://developer.android. com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)

...或 http://developer.android.com/参考/android/hardware/Camera.html#setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback)以更好地控制时间。

You can try capturing subsequent preview frames in preallocated byte arrays.
See the following methods:

http://developer.android.com/reference/android/hardware/Camera.html#addCallbackBuffer(byte[])
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)

...or http://developer.android.com/reference/android/hardware/Camera.html#setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback) for better control over timing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文