Учебник по работе с камерой для Android (с использованием SurfaceView)

Вот мой пример кода:

package newslab.video.server;

import android.app.Activity;
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.widget.Button;
import android.widget.TextView;

public class VideoServer extends Activity implements SurfaceHolder.Callback {
    TextView testView;

    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;

    private final String tag = "VideoServer";

    Button start, stop;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        start = (Button)findViewById(R.id.btn_start);
        start.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View arg0) {
                start_camera();
            }
        });

        stop = (Button)findViewById(R.id.btn_stop);
        stop.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View arg0) {
                stop_camera();
            }
        });

        surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private void start_camera() {
        try{
            camera = Camera.open();
        }catch(RuntimeException e){
            Log.e(tag, "init_camera: " + e);
            return;
        }
        Camera.Parameters param;
        param = camera.getParameters();
        //modify parameter
        param.setPreviewFrameRate(20);
        param.setPreviewSize(176, 144);
        camera.setParameters(param);
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
        } catch (Exception e) {
            Log.e(tag, "init_camera: " + e);
            return;
        }
    }

    private void stop_camera() {
        camera.stopPreview();
        camera.release();
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }
}

Однако он просто показывает предварительный просмотр и останавливает камеру.
Есть ли какой-либо другой учебник для обучения дальнейшей обработке, например, как сохранить изображение или обработать изображение с растровым изображением?


person jjLin    schedule 05.09.2012    source источник
comment
не использование штатной камеры означает что? какую камеру вы используете?   -  person Narendra Pal    schedule 05.09.2012
comment
у вас есть решение вашего основного запроса?   -  person Narendra Pal    schedule 05.09.2012
comment
еще один вопрос для комментария ниже ^^   -  person jjLin    schedule 05.09.2012


Ответы (5)


В порядке. Итак, вот решение:

Я не добавляю никаких попыток поймать. Это просто для захвата изображения и его сохранения на SD-карту.

public class VideoServer extends Activity implements SurfaceHolder.Callback {
    TextView testView;

    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    PictureCallback rawCallback;
    ShutterCallback shutterCallback;
    PictureCallback jpegCallback;
    private final String tag = "VideoServer";

    Button start, stop, capture;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        start = (Button)findViewById(R.id.btn_start);
        start.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View arg0) {
                start_camera();
            }
        });
        stop = (Button)findViewById(R.id.btn_stop);
        capture = (Button) findViewById(R.id.capture);
        stop.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View arg0) {
                stop_camera();
            }
        });
        capture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                captureImage();
            }
        });

        surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        rawCallback = new PictureCallback() {
            public void onPictureTaken(byte[] data, Camera camera) {
                Log.d("Log", "onPictureTaken - raw");
            }
        };

        /** Handles data for jpeg picture */
        shutterCallback = new ShutterCallback() {
            public void onShutter() {
                Log.i("Log", "onShutter'd");
            }
        };
        jpegCallback = new PictureCallback() {
            public void onPictureTaken(byte[] data, Camera camera) {
                FileOutputStream outStream = null;
                try {
                    outStream = new FileOutputStream(String.format(
                            "/sdcard/%d.jpg", System.currentTimeMillis()));
                    outStream.write(data);
                    outStream.close();
                    Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                }
                Log.d("Log", "onPictureTaken - jpeg");
            }
        };
    }

    private void captureImage() {
        // TODO Auto-generated method stub
        camera.takePicture(shutterCallback, rawCallback, jpegCallback);
    }

    private void start_camera()
    {
        try{
            camera = Camera.open();
        }catch(RuntimeException e){
            Log.e(tag, "init_camera: " + e);
            return;
        }
        Camera.Parameters param;
        param = camera.getParameters();
        //modify parameter
        param.setPreviewFrameRate(20);
        param.setPreviewSize(176, 144);
        camera.setParameters(param);
        try {
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            //camera.takePicture(shutter, raw, jpeg)
        } catch (Exception e) {
            Log.e(tag, "init_camera: " + e);
            return;
        }
    }

    private void stop_camera()
    {
        camera.stopPreview();
        camera.release();
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

}

Не нажимайте кнопку захвата до старта, потому что я не проверял это. Я просто хотел показать вам, как захватить и сохранить изображение на sdcard.

person Narendra Pal    schedule 05.09.2012
comment
для получения дополнительной информации посетите этот сайт marakana.com/forums/android/examples/39.html - person Narendra Pal; 05.09.2012
comment
Ваше решение идеально. Но еще один вопрос, как я могу получить захваченное изображение в виде растрового изображения, чтобы добиться дальнейшего эффекта? - person jjLin; 05.09.2012
comment
для этого вам нужно взять захваченное изображение с SD-карты, используя это. Растровое изображение = BitmapFactory.decodeFile(/path/images/imageName.jpg); И вы можете выполнять дальнейшие операции с растровым изображением - person Narendra Pal; 05.09.2012
comment
@NarendraPal, когда я нажимаю кнопку «Пуск», отображается: java.lang.RuntimeException: не удалось подключиться к службе камеры на logcat - person mahdi; 03.06.2014
comment
@mahdi, пожалуйста, просмотрите полный пример кода, который я упоминаю в комментариях, и дайте мне знать, если он не работает. - person Narendra Pal; 04.06.2014
comment
@NarendraPal Я не могу получить доступ к этой ссылке, не могли бы вы мне помочь? - person arvind.mohan; 22.05.2016
comment
я хотел бы добавить это в приложение виджета, но вид поверхности не разрешен, есть идеи?? - person Tayseer; 10.10.2016

Не забудьте получить разрешение на использование камеры в файле манифеста Android,

<uses-permission android:name="android.permission.CAMERA" ></uses-permission>

Также вы должны получить разрешение на хранение изображений на SD-карте,

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
person Sahil Mahajan Mj    schedule 05.09.2012

Разрешение камеры в manifiest файле:

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />

Разрешение на сохранение изображения из sdcard в manifiest файле:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
person Kunal Dharaiya    schedule 20.03.2017

У меня были проблемы с камерой, я пытался понять, как реализовать и работать с ней, и наткнулся на следующие ресурсы: Предварительный просмотр камеры. В нижней части страницы у вас есть примеры наиболее распространенных сценариев, а также сценарий в исходном вопросе: Сделайте и просмотрите фотографию

person ViksaaSkool    schedule 20.07.2014

Если вы используете Android 10 или более позднюю версию, не забудьте добавить это в свой файл манифеста.

android:requestLegacyExternalStorage="true"
android:grantUriPermissions="true"
person Syed Rafaqat Hussain    schedule 28.09.2020