Android SurfaceView拍照录像实现方法

作者:Smile_muse 时间:2022-06-18 17:07:20 

Surface的拍照实现也是很简单,一个小demo就可以把流程看懂了。

话不多说,直接上代码

布局文件


<SurfaceView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/sv_main_surface"
   />

<Button
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:onClick="tackPhoto"
   android:text="拍照"
   />

Activity


public class MainActivity extends AppCompatActivity {

private SurfaceView sv_main_surface;
 private Camera camera;

@Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   sv_main_surface = (SurfaceView) findViewById(R.id.sv_main_surface);

//添加surface回调函数
   sv_main_surface.getHolder().addCallback(new SurfaceHolder.Callback() {

@Override//控件创建时,打开照相机
     public void surfaceCreated(SurfaceHolder holder) {
       //打开照相机
       camera = Camera.open();
       //设置参数
       Camera.Parameters parameters=camera.getParameters();
       parameters.setPictureFormat(PixelFormat.JPEG);
       parameters.set("jpeg-quality",85);
       camera.setParameters(parameters);
       //将画面展示到SurfaceView
       try {
         camera.setPreviewDisplay(sv_main_surface.getHolder());
       } catch (IOException e) {
         e.printStackTrace();
       }
       //开启预览效果
       camera.startPreview();

}

@Override//控件改变
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override//控件销毁
     public void surfaceDestroyed(SurfaceHolder holder) {
       //照相同一时刻只能允许一个软件打开
       if(camera!=null){
         camera.stopPreview();
         camera.release();//释放内存
         camera=null;
       }
     }
   });

}

public void takePhoto(View view){
   camera.takePicture(null, null, new Camera.PictureCallback() {
     @Override
     public void onPictureTaken(byte[] bytes, Camera camera) {
       //技术:图片压缩技术(如果图片不压缩,图片大小会过大,会报一个oom内存溢出的错误)
       Bitmap bitmap= BitmapFactory.decodeByteArray(bytes,0,bytes.length);
       try {
         FileOutputStream fos = new FileOutputStream("/mnt/sdcard/qq"+System.currentTimeMillis()+".png");//图片保存路径
         bitmap.compress(Bitmap.CompressFormat.PNG,85,fos);//压缩格式,质量,压缩路径

camera.stopPreview();
         camera.startPreview();
       } catch (FileNotFoundException e) {
         e.printStackTrace();
       }
     }
   });

}
}

我们还要添加权限


  <!--打开照相机的权限-->
 <uses-permission android:name="android.permission.CAMERA"></uses-permission>
 <!--创建文件的权限-->
 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
 <!--写内存卡的权限-->
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

就这样一个小案例就完成了

既然可以拍照,那肯定也是可以录像的,所以我们再来看看录像是怎么实现的

布局文件


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_media_recorder"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:paddingBottom="@dimen/activity_vertical_margin"
 android:paddingLeft="@dimen/activity_horizontal_margin"
 android:paddingRight="@dimen/activity_horizontal_margin"
 android:paddingTop="@dimen/activity_vertical_margin"
 tools:context="com.zking.familyapp.MediaRecorderActivity">

<SurfaceView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:id="@+id/sv_media_surface"
   />

<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   ></LinearLayout>

<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="开始"
   android:onClick="start"
   />
<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="停止"
   android:onClick="stop"
   />

</RelativeLayout>

Activity


public class MediaRecorderActivity extends AppCompatActivity {

private SurfaceView sv_media_surface;
 private MediaRecorder mediaRecorder;

@Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_media_recorder);
   sv_media_surface = (SurfaceView) findViewById(R.id.sv_media_surface);

//实例化媒体录制器
   mediaRecorder = new MediaRecorder();
 }

public void start(View view){
   mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
   mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

//设置格式
   mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
   mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

//设置保存路径
   mediaRecorder.setOutputFile("/mnt/sdcard/uu"+System.currentTimeMillis()+".mp4");

mediaRecorder.setPreviewDisplay(sv_media_surface.getHolder().getSurface());

try {
     mediaRecorder.prepare();
     mediaRecorder.start();
   } catch (IOException e) {
     e.printStackTrace();
   }
 }

public void stop(View view){
   if(mediaRecorder!=null){
     mediaRecorder.stop();
     mediaRecorder.release();
     mediaRecorder=null;
   }

}
}

添加权限


<!-- 录像的权限-->
 <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
标签:Android,SurfaceView,拍照,录像
0
投稿

猜你喜欢

  • 微信公众平台开发教程(三) 基础框架搭建

    2022-08-12 00:33:50
  • Springboot创建项目的图文教程(idea版本)

    2022-09-30 13:30:17
  • MyBatis中使用$和#所遇到的问题及解决办法

    2023-03-25 12:27:55
  • SpringBoot工程搭建打包、启动jar包和war包的教程图文详解

    2022-05-04 22:09:10
  • JAVA Spring中让人头痛的JAVA大事务问题要如何解决你知道吗

    2023-01-14 04:58:04
  • 合成聚合复用原则_动力节点Java学院整理

    2023-06-27 22:05:20
  • Android刮刮卡功能具体实现代码

    2021-08-06 04:12:24
  • 通过实例解析JMM和Volatile底层原理

    2023-05-20 19:10:48
  • java对象拷贝详解及实例

    2023-01-20 08:27:00
  • 为什么Spring官方推荐的@Transational还能导致生产事故

    2022-02-13 15:54:37
  • 示例解析java面向对象编程封装与访问控制

    2021-10-18 19:55:19
  • 手写java性能测试框架第二版

    2023-03-15 14:07:31
  • 简单讲解java中throws与throw的区别

    2022-06-01 05:16:55
  • Java使用Jdbc连接Oracle执行简单查询操作示例

    2021-07-25 03:34:25
  • JAVA实现长连接(含心跳检测Demo)

    2023-08-05 09:51:13
  • c语言switch反汇编的实现

    2023-06-29 03:38:17
  • Java SpringBoot实现带界面的代码生成器详解

    2023-09-28 11:54:14
  • Android实现简易浏览器遇到问题的解决方法

    2023-06-15 21:47:56
  • Android 通过代码安装 APK的方法详解

    2022-11-12 14:37:26
  • 基于WPF实现步骤控件的示例代码

    2021-09-12 15:16:16
  • asp之家 软件编程 m.aspxhome.com