我的应用程序启动时,如何在没有预览的情况下从相机拍照?

时间:2013-12-19 14:42:24

标签: android android-intent

现在我想要的只是一个应用程序,它可以在启动时从相机拍摄照片。没有布局,没有相机预览......没有,只是一个简单的应用程序图标来启动应用程序。一旦启动,相机应该拍照。

这是预览图片,我不想在我的应用中显示。我只是想将我的应用程序设置为点击图片中包围的拍照按钮

enter image description here

拍完照片后,我需要将照片保存在照片库中。

有人可以在这里指导我吗?感谢

以下是我在仿真器和设备上尝试过的一些代码。

import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;

public class Main extends Activity implements SurfaceHolder.Callback{

    private Camera camera;
     private ImageButton cameraClick;
     private SurfaceHolder mHolder; 

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

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

      cameraClick = (ImageButton) findViewById(R.id.cameraClick);
      cameraClick.setOnClickListener( new OnClickListener() {
       public void onClick(View v)
       {
            camera.takePicture(shutterCallback, rawCallback,jpegCallback);
       }
      });  





      }

     // Handles when shutter open
     ShutterCallback shutterCallback = new ShutterCallback()
     {
      public void onShutter()
      {   

      }
     };

     /** Handles data for raw picture */
     PictureCallback rawCallback = new PictureCallback()
     {
      public void onPictureTaken(byte[] data, Camera camera)
      {   

      }
     }; 

     /** Handles data for jpeg picture */
     PictureCallback jpegCallback = new PictureCallback()
    {
      public void onPictureTaken(byte[] data, Camera camera)
    {
       // we do something using return byte[] of taken image.
      }
     };

     @Override
     public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)
    {

      // Set camera preview size,orientation,rotation using parameters 

    Camera.Parameters parameters = camera.getParameters();
            parameters.set("orientation", "portrait");
            camera.setParameters(parameters);
             camera.startPreview();       

     }

     @Override
     public void surfaceCreated(SurfaceHolder holder)
    {
      camera = Camera.open();
             try {
        camera.setPreviewDisplay(holder);
       }
    catch (IOException e)
    {
        e.printStackTrace();
       }

     }

     @Override
     public void surfaceDestroyed(SurfaceHolder holder)
    {
      camera.stopPreview();
             camera.release();
            camera = null; 

     }

}

现在,我可以听到图片点击按钮,同时点击模拟器和设备。现在我想保存图片。任何线索?

5 个答案:

答案 0 :(得分:19)

使用以下代码。它经过测试并为我工作。任何问题请随时发表评论。

private void takeSnapShots()
{
      Toast.makeText(getApplicationContext(), "Image snapshot   Started",Toast.LENGTH_SHORT).show();
     // here below "this" is activity context.  
 SurfaceView surface = new SurfaceView(this);
    Camera camera = Camera.open();
    try {
        camera.setPreviewDisplay(surface.getHolder());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    camera.startPreview();
    camera.takePicture(null,null,jpegCallback);
}


 /** picture call back */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) 
{
    FileOutputStream outStream = null;
    try {
  String dir_path = "";// set your directory path here
        outStream = new FileOutputStream(dir_path+File.separator+image_name+no_pics+".jpg");    
        outStream.write(data);
        outStream.close();
        Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally 
    {
        camera.stopPreview();
        camera.release();
        camera = null;
        Toast.makeText(getApplicationContext(), "Image snapshot Done",Toast.LENGTH_LONG).show();


    }
    Log.d(TAG, "onPictureTaken - jpeg");
}
};

答案 1 :(得分:11)

从API级别11开始,添加了SurfaceTexture。有了它,不再需要SurfaceView。我用三星Galaxy S3 Neo测试了以下代码。

mCamera = Camera.open();
try {
    mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e1) {
    Log.e(Version.APP_ID, e1.getMessage());
}

Parameters params = mCamera.getParameters();
params.setPreviewSize(640, 480);
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
params.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(params);
mCamera.startPreview();
mCamera.takePicture(null, null, null, new PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(Version.APP_ID, "picture-taken");
    }
});

答案 2 :(得分:2)

相机预览只是您布局中的一种特殊视图,因此如果您不想显示它但仍然使用现有代码而无需进行大量修改,那么您可以执行一些操作。< / p>

例如,在您添加相机预览SurfaceView的布局文件中,您只需在其上添加另一个视图即可阻止预览。这样你仍然可以使用你现有的代码,而不会修改太多,相机预览将像以前一样工作,但你会发现你正在寻找的效果不是显示相机预览。

答案 3 :(得分:1)

我已经尝试过你需要之前和之后很多研究发现,由于某种原因,你必须开始预览,甚至在SurfaceView中显示内容才能得到图片,显然是后面的系统场景刷新了SurfaceView渲染预览的缓冲区中的任何内容,现在我所做的是克服这个问题(拍摄没有预览的图片)只是将我的布局中的SurfaceView设置为1dp宽度和1dp高度(请注意它必须是1dp,0dp会导致崩溃)。

<SurfaceView
   android:layout_width="1dp"
   android:layout_height="1dp"/>

绝对可能不是一个非常优雅的方式来摆脱“预览”图像,但它绝对有效,让我有空间去做我想到的其他事情。

希望这会有所帮助......

此致

答案 4 :(得分:0)

对于那些想要做同样事情的人,但使用 CAMERA 2 API ,你可以在这里查看我的答案。 Capture picture without preview using camera2 API