当前位置: 首页 > news >正文

Android Studio新手开发第三十四天

       

目录

使用系统相机拍摄照片      

使用Camera和SurfaceView自行实现

         对于手机拍照的APP而言,有两种实现方式,一种是借助系统相机来拍摄照片,另一种是通过Camera工具联合表面视图SurfaceView自行规划编码细节。两者有各自的优缺点,可以按需选择。

使用系统相机拍摄照片      

        利用系统相机拍摄照片有其优势以及缺点,具体说明如下:

优点:

  1. 开发简单:只需要几行代码就可以启动系统相机应用,无需处理复杂的相机操作。

  2. 稳定性高:系统相机经过长期测试和优化,通常比自定义相机更稳定。

  3. 功能丰富:系统相机通常提供多种拍摄模式、滤镜和设置,用户熟悉且可以直接使用。

  4. 兼容性好:不同设备上的系统相机会处理硬件和驱动的差异,避免了兼容性问题。

缺点:

  1. 定制性差:无法自定义相机界面和功能,只能使用系统提供的界面。

  2. 依赖系统:如果设备上没有相机应用,或者相机应用出现故障,则无法使用。

  3. 返回数据可能受限:返回的图片可能是缩略图或者经过压缩的图片(如果没有指定输出文件)。

        获取系统相机拍摄的照片有两种方式,一个是获取缩略图,另一个是保存拍摄的照片后读取该照片,此时获取的照片为原始图片。示例代码如下,在布局文件中添加两个按钮以及一个文本视图、一个图片视图。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MultiMedia.SnapBySystemCameraActivity"android:orientation="vertical"><Buttonandroid:id="@+id/button_Snap"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="用系统相机拍照获取缩略图"/><Buttonandroid:id="@+id/button_Snap_Origin"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="用系统相机拍照获取原始照片"/><TextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="wrap_content"/><ImageViewandroid:id="@+id/imageView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@drawable/image_1" /></LinearLayout>

        部分Java代码如下,主要看两个活动结果启动器的内容以及方法takeOriginalPhoto的内容,第一个启动器返回的是一个Bitmap类型的数据,可以直接将Bitmap赋给ImageView;第二个启动器返回的是一个布尔类型,表示是否拍照成功,若成功则可以通过在takeOriginalPhoto方法中获取的Uri来打开已保存的图片并将其转化为Bitmap类型赋给ImageView,示例代码中的图片保存在系统相册中,可以在系统相册中找到拍摄的照片。如果只是需要简单的图片那么第一种方式已经足够了,代码量少且简单实现。

public class SnapBySystemCameraActivity extends AppCompatActivity implements View.OnClickListener {private final String TAG = "SnapBySystemCamera";private Button button_Snap, button_Snap_Origin;private TextView textView;private ImageView imageView;private ActivityResultLauncher activityResultLauncher_Original;     //活动结果启动器(原始图)private ActivityResultLauncher activityResultLauncher_Thumbnail;    //活动结果启动器(缩略图)private Uri mImageUri;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_snap_by_system_camera);initView();}//初始化页面视图private void initView() {button_Snap = findViewById(R.id.button_Snap);button_Snap_Origin = findViewById(R.id.button_Snap_Origin);textView = findViewById(R.id.textView);imageView = findViewById(R.id.imageView);// 注册一个善后工作的活动结果启动器,准备打开拍照界面(返回缩略图)activityResultLauncher_Thumbnail = registerForActivityResult(new ActivityResultContracts.TakePicturePreview(),bitmap_Thumbnail -> imageView.setImageBitmap(bitmap_Thumbnail));// 注册一个善后工作的活动结果启动器,准备打开拍照界面(返回原始图)activityResultLauncher_Original = registerForActivityResult(new ActivityResultContracts.TakePicture(),if_success -> {if (if_success) {try (InputStream inputStream = getContentResolver().openInputStream(mImageUri)) {Bitmap bitmap = BitmapFactory.decodeStream(inputStream);textView.setText("原始图拍照结果如下:");imageView.setImageBitmap(bitmap); // 设置图像视图的位图对象} catch (Exception e) {Log.d(TAG, "onActivityResult: " + e.getMessage());}}});button_Snap.setOnClickListener(this);button_Snap_Origin.setOnClickListener(this);}@Overridepublic void onClick(View view) {if (view.getId() == R.id.button_Snap) {Log.d(TAG, "onClick: button_Snap");activityResultLauncher_Thumbnail.launch(null);} else if (view.getId() == R.id.button_Snap_Origin) {Log.d(TAG, "onClick: button_Snap_Origin");takeOriginalPhoto();}}// 拍照时获取原始图片private void takeOriginalPhoto() {// Android10开始必须由系统自动分配路径,同时该方式也能自动刷新相册ContentValues values = new ContentValues();Calendar calendar = Calendar.getInstance();String time = String.format("%s%s%s%s", calendar.get(Calendar.HOUR_OF_DAY),calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND));// 指定图片文件的名称values.put(MediaStore.Images.Media.DISPLAY_NAME, "photo_" + time);values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // 类型为图像// 通过内容解析器插入一条外部内容的路径信息mImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);activityResultLauncher_Original.launch(mImageUri);}
}

        效果图如下,第一张为刚进入页面,第二张为拍摄获取缩略图,第三张为拍摄获取原始图。可以看到两张照片之间大小是不一致的,第一张若放大到与第二张一样的宽高,它的效果会更加模糊。

使用Camera和SurfaceView自行实现

        利用Camera以及SurfaceView实现拍照的优缺点如下说明:

优点

  1. 高度定制:可以完全自定义相机界面和拍摄流程,满足特定业务需求。

  2. 控制精细:可以控制相机的各种参数(如对焦、曝光、闪光灯等)和拍摄过程。

  3. 无缝体验:可以将相机功能完全集成到应用中,提供一致的用户体验。

缺点

  1. 开发复杂:需要处理相机的打开、预览、参数设置、拍照、释放等整个生命周期,代码量大。

  2. 兼容性挑战:不同设备的相机硬件和驱动可能有差异,需要处理各种兼容性问题。

  3. 稳定性风险:自行管理的相机可能因为操作不当导致崩溃或性能问题。

  4. 功能实现成本高:如变焦、美颜、滤镜等功能都需要自行开发或集成第三方库。

        下面的示例代码是比较简单的,若想要学习更加高深的可以另找其他厉害的博主,作者也才刚学不久。示例代码如下,在布局文件中添加一个按钮、一个SurfaceView以及一个ImageView。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MultiMedia.CameraWithSurfaceViewActivity"android:orientation="vertical"><Buttonandroid:id="@+id/button_Snap"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="点击拍照"/><SurfaceViewandroid:id="@+id/surfaceView"android:layout_width="match_parent"android:layout_height="300dp"/><ImageViewandroid:id="@+id/imageView"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

        部分Java代码如下,主要看方法initCamera以及按钮监听器中的逻辑处理代码。

public class CameraWithSurfaceViewActivity extends AppCompatActivity {private SurfaceView surfaceView;private Button button_Snap;private ImageView imageView;private SurfaceHolder surfaceHolder;private Camera camera;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_camera_with_surface_view);initView();}private void initView() {button_Snap = findViewById(R.id.button_Snap);imageView = findViewById(R.id.imageView);surfaceView = findViewById(R.id.surfaceView);surfaceHolder = surfaceView.getHolder();surfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {initCamera();}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {}});button_Snap.setOnClickListener(view -> camera.takePicture(null, null, new Camera.PictureCallback() {@Overridepublic void onPictureTaken(byte[] bytes, Camera camera) {Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);imageView.setImageBitmap(bitmap);}}));}private void initCamera() {// 初始化 Camera,0 通常代表后置摄像头camera = Camera.open(0);// 调整摄像头预览角度,例如设置为90度camera.setDisplayOrientation(90);// 设置SurfaceView不维护自己的缓冲区surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 将Camera的预览输出与SurfaceView关联try {camera.setPreviewDisplay(surfaceHolder);} catch (IOException e) {Log.d(TAG, "initializeCamera: " + e.getMessage());}camera.startPreview(); // 开始预览}}

        效果图如下,图片中第一个图片为SurfaceView,第二个为ImageView。

http://www.dtcms.com/a/545298.html

相关文章:

  • 多维c++ vector, vector<pair<int,int>>, vector<vector<pair<int,int>>>示例
  • 【TVM 教程】自定义优化
  • 免费行情网站大全下载成品源码网站
  • 男女生做羞羞事情的网站网站域名怎样选择
  • 做政协网站软件的公司找人做网站 优帮云
  • 电力系统安全新样本:瑞数信息用“动态安全”筑起业务防线
  • 基于Python(Tkinter)实现(图形界面)小说阅读器
  • 选ThinkPad还是ThinkBook?联想乐享智能体让你告别选择困难!
  • 企业网站seo优化怎么做个人网站建设小江
  • 4种智能方法:如何将SIM卡中的短信转移到电脑
  • 【2D/3D户型图编辑器实现-技术栈选择】附demo演示
  • 信息网站开发网络公司人工智能公众号
  • SpringBoot15-项目部署
  • 安卓玩机工具推荐------ROOT与免ROOT安卓设备玩机工具
  • 【视觉slam十四讲】【十二讲 建图】12.1 习题:证明两个正态分布的联合分布
  • 【大数据高并发核心场景实战】 数据持久化层 - 查询分离
  • 一键阿里云 wordpress在门户网站做产品seo
  • 互联网站建设机构搭建网站大概多少钱
  • JavaScript DOM节点操作详解
  • Ultralytics 代码库深度解读【三】:YOLO V8/V11 核心模块可视化拆解(网络结构与参数解析)
  • 佰力博检测与您探讨压电陶瓷圆柱纵向振动模式
  • 32岁学做网站石家庄网站建设平台有哪些
  • 基于 51 单片机的智能手势控制小车设计与实现
  • 做暧免费网站wordpress 关闭更新警告
  • 网站开发好吗软件外包公司有哪些
  • 使用Deeplabv3+进行遥感影像土地利用分类
  • 深度学习之图像分割:从基础概念到核心技术全解析
  • Linux-unzip解压命令的安装与使用
  • 基于深度学习技术实现染色质开放区域的预测与分析系统源代码+数据库,采用Flask + Vue3 实现前后端分离的植物染色质可及性预测系统
  • 7.OpenStack管理(一)