Android如何调用摄像头

举报
黄啊码 发表于 2022/06/29 00:37:34 2022/06/29
【摘要】 我们要调用摄像头的拍照功能,显然 第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码 <uses-permission android:name="android.permission.CAMERA"/>//摄像头权限...

我们要调用摄像头的拍照功能,显然

第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码

<uses-permission android:name="android.permission.CAMERA"/>//摄像头权限

SD卡读写权限

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

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

第二步,要将摄像头捕获的图像实时地显示在手机上。

我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码

<SurfaceView

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:id="@+id/surfaceview"

/>

第三步,设置窗口的显示方式

首先获得当前窗口Windowwindow = getWindow();//得到窗口

接着设置没有标题requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题

接着设置全屏 window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏

当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码

window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮

至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)

setContentView(R.layout.main);

第四步,设置SurficeView显示控件的属性

找到surficeView

surfaceView = (SurfaceView)findViewById(R.id.surfaceview);

设置它的像素为800x600

surfaceView.getHolder().setFixedSize(800,480);

//下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前

surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

第五步,就是为surficeView加入回调方法(callBack)

surfaceView.getHolder().addCallback(newSurfaceCallback());

上面的回调类是我们自己定义的,代码如下

private class SurfaceCallback implementsSurfaceHolder.Callback{

@Override

public void surfaceCreated(SurfaceHolderholder) {

try {

camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera

WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器

Display display = wm.getDefaultDisplay();//得到当前屏幕

Camera.Parameters parameters =camera.getParameters();//得到摄像头的参数

parameters.setPreviewSize(display.getWidth(),display.getHeight());//设置预览照片的大小

parameters.setPreviewFrameRate(3);//设置每秒3

parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的格式

parameters.setJpegQuality(85);//设置照片的质量

parameters.setPictureSize(display.getHeight(),display.getWidth());//设置照片的大小,默认是和屏幕一样大

camera.setParameters(parameters);

camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面

camera.startPreview();//开始预览

isPreview = true;//设置是否预览参数为真

} catch (IOException e) {

Log.e(TAG, e.toString());

}

}

 

@Override

public void surfaceChanged(SurfaceHolderholder, int format, int width,

int height) {

// TODO Auto-generated method stub

}

@Override

public void surfaceDestroyed(SurfaceHolderholder) {

if(camera!=null){

if(isPreview){//如果正在预览

camera.stopPreview();

camera.release();

}

}

}

}

第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下

public boolean onKeyDown(int keyCode,KeyEvent event) {//处理按键事件

if(camera!=null&&event.getRepeatCount()==0)//代表只按了一下

{

switch(keyCode){

case KeyEvent.KEYCODE_BACK://如果是搜索键

camera.autoFocus(null);//自动对焦

break;

case KeyEvent.KEYCODE_DPAD_CENTER://如果是中间键

camera.takePicture(null, null, new TakePictureCallback());//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中

break;

}

}

return true;//阻止事件往下传递,否则按搜索键会变成系统默认的

}

------------------------------------------------------------------------------------------

private final class TakePictureCallbackimplements PictureCallback{

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

try {

Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0, data.length);

File file = newFile(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");

FileOutputStream outputStream = newFileOutputStream(file);

bitmap.compress(CompressFormat.JPEG, 100,outputStream);

outputStream.close();

camera.stopPreview();

camera.startPreview();//处理完数据之后可以预览

} catch (Exception e) {

Log.e(TAG, e.toString());

}

}

}

注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。

文章来源: markwcm.blog.csdn.net,作者:黄啊码,版权归原作者所有,如需转载,请联系作者。

原文链接:markwcm.blog.csdn.net/article/details/8805053

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。