【问题标题】:How to take pictures from the camera without preview when my app starts?我的应用程序启动时如何在没有预览的情况下从相机拍照?
【发布时间】:2014-01-08 04:33:48
【问题描述】:

现在我想要的只是一个在启动时从相机中拍照的应用程序。没有布局,没有相机预览......什么都没有,只是一个简单的应用程序图标来启动应用程序。一旦启动,相机应该会拍照。

这是预览图像,我不想出现在我的应用中。我只想让我的应用程序点击图片中环绕的拍照按钮

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

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

这是我在模拟器和设备上尝试过的一些代码。

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; 

     }

}

现在我可以听到点击模拟器和设备上的按钮的图片。现在我也想保存图片。有什么线索吗?

【问题讨论】:

  • 我查看了示例代码。任何地方都没有提到这样的功能或特性。
  • 如果我正确理解了您的问题,您只需要整个布局中的一个按钮,在点击时点击照片而不进行预览吗?
  • @AbhishekV 绝对正确!这是我需要的。
  • 那么您提供的答案应该可以正常工作
  • @Muhammad Maqsoodur R 在任何可以隐藏surfaceView的布局后面使用surfaceView。在您的情况下,通过在该表面视图上进行设计布局来隐藏表面视图

标签: android android-intent


【解决方案1】:

使用下面的代码。它经过测试并为我工作。有任何问题请随时提出 cmets。

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");
}
};

【讨论】:

  • SurfaceView 表面 = 新 SurfaceView(this);给我一个空对象引用
  • 你应该在活动中使用一段代码,或者尝试传递活动上下文
  • 抱歉之前的评论...实际上它在这一行中给出了空对象引用 camera.setPreviewDisplay(surface.getHolder());
  • 检查哪个上下文正在通过表面创建。请尝试设置活动上下文。
  • 图片顺时针旋转90度
【解决方案2】:

从 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");
    }
});

【讨论】:

  • SurfaceTexture 需要camera.startPreview() 呼叫。它与SurfaceView 非常相似。所以我无法通过SurfaceTexture 逃脱预览“冻结”。
【解决方案3】:

相机预览只是布局中的一种特殊视图,因此,如果您不想显示它但仍使用现有代码而无需进行大量修改,则可以使用一些技巧。

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

【讨论】:

  • 但从性能的角度来看并不是一个很好的方法。如果我们遵循SurfaceTexture 方式,我们将有一层额外的透支可以避免..
【解决方案4】:

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

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

摆脱“预览”图像绝对不是一种非常优雅的方式,但它确实可以解决问题,让我有空间去做我想做的所有其他事情。

希望这会有所帮助...

问候

【讨论】:

    【解决方案5】:

    对于那些正在寻找做同样事情但使用 CAMERA 2 API 的人,您可以在此处查看我的答案。 Capture picture without preview using camera2 API.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 2020-11-03
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多