【问题标题】:Building my own camera application + Automatically capture the image构建我自己的相机应用程序 + 自动捕获图像
【发布时间】:2017-08-04 14:10:11
【问题描述】:

我创建了自己的相机应用程序。当我单击按钮时,它会拍照并将其保存在相册中。我想要做的是在没有预览且不点击任何按钮的情况下拍摄照片。

我的主要活动课。

package themiya.camera.android;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;

public class CameraActivity extends Activity {

private Camera mCamera;
private CameraPreview mPreview;
public static final int MEDIA_TYPE_IMAGE = 1;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button captureButton = (Button) findViewById(R.id.button_capture);
    System.out.println("Starting!");

    // Create an instance of Camera
    mCamera = getCameraInstance();
    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);

    final PictureCallback mPicture = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {

            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);

            if (pictureFile == null){
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                MediaStore.Images.Media.insertImage(getContentResolver(), pictureFile.getAbsolutePath(), pictureFile.getName(), pictureFile.getName());
            } catch (FileNotFoundException e) {

            } catch (IOException e) {

            }
          }
        };





     // Add a listener to the Capture button
        captureButton.setOnClickListener(

            new View.OnClickListener() {

                public void onClick(View v) {
                    // get an image from the camera   

                    System.out.println("Photo Taking!");
                    mCamera.takePicture(null, null, mPicture);



                }
            }
        );




}




/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

@Override
protected void onPause() {
    super.onPause();
    releaseCamera();              // release the camera immediately on pause event
}



private void releaseCamera(){
    if (mCamera != null){
        mCamera.release();        // release the camera for other applications
        mCamera = null;
    }
}



/** Create a File for saving an image or video */
private  File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");


    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else {
        return null;
    }

    return mediaFile;
}
}

还有预览课。

package themiya.camera.android;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context,Camera camera) {
        super(context);
        mCamera = camera;

        /*SurfaceView view = new SurfaceView(this);
        c.setPreviewDisplay(view.getHolder());
        c.startPreview();
        c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
         * */

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();

        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);   


    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub

        if (mHolder.getSurface() == null){
            // preview surface does not exist
            return;
          }

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

          // set preview size and make any resize, rotate or
          // reformatting changes here

          // start preview with new settings
          try {
              mCamera.setPreviewDisplay(mHolder);
              mCamera.startPreview();

          } catch (Exception e){

          }

    }

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

    }

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

    }

}

activity类中的on click方法是这样的。

captureButton.setOnClickListener(

            new View.OnClickListener() {

                public void onClick(View v) {
                        // get an image from the camera   

                    System.out.println("Photo Taking!");
                    mCamera.takePicture(null, null, mPicture);



                }
            }
        );

当我删除那个监听器部分并只放

mCamera.takePicture(null, null, mPicture);

部分应用程序崩溃。我认为这可能是由于应用程序打开相机所需的延迟。所以代码尝试在打开相机之前获取照片。还要等待(10000);对我没用。

我还想在没有预览的情况下拍照。据我所知,我必须更改预览课程才能做到这一点。但我不知道正确的做法。

谁能帮我解决这个问题。

【问题讨论】:

  • 好的我找到了自动拍照的答案.... final Timer t = new Timer(); t.schedule(new TimerTask() { @Override public void run() { mCamera.takePicture(null, null, mPicture); t.cancel(); } },5000);现在我想停止预览...

标签: android android-camera


【解决方案1】:

诀窍是给相机类一个不属于视图层次结构的 SurfaceView。以下代码来自我的一个应用程序,我使用这种技术来显示我自己的

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mCamera = Camera.open();
        startPreview();
    }

    private void startPreview() {
            if (mCamera != null) {
                mCamera.stopPreview();
                try {
                    mCamera.setPreviewDisplay(new SurfaceView(this).getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mCamera.setPreviewCallbackWithBuffer(this);

                Camera.Parameters parameters = mCamera.getParameters();    
                parameters.setPreviewSize(IMAGE_W, IMAGE_H);
                mCamera.setParameters(parameters);
                PixelFormat p = new PixelFormat();
                PixelFormat.getPixelFormatInfo(parameters.getPreviewFormat(), p);
                int bufSize = (IMAGE_W * IMAGE_H * p.bitsPerPixel) / 8;
                mCamera.addCallbackBuffer(new byte[bufSize]);
                mCamera.startPreview();
            }
        }
    public void onPreviewFrame(final byte[] data, Camera camera) {
        if (mCamera == null) {
            return;
        }
        mCamera.addCallbackBuffer(data);
    }
}

【讨论】:

    【解决方案2】:

    好的,我找到了自动拍照的答案。添加为评论以供他人使用。

    final Timer t = new Timer();
    t.schedule(new TimerTask() { 
    @Override 
    public void run() { 
    mCamera.takePicture(null, null, mPicture); t.cancel(); 
    } 
    },5000);
    

    【讨论】:

      【解决方案3】:

      它很简单地创建另一个方法,它带有一个具有 10000 延迟的计时器变量,它完成了预览活动,然后你就完成了。逻辑是这些方法将在计时器 1 活动完成后运行 5 秒。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-26
        • 2017-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多