Android实现调用手机摄像头进行拍照并存储为文件

声明权限

首先应该在“AndroidManifest”文件中声明手机内存读写权限:

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

由于从Android 6.0开始,一些敏感权限需要在对应的Activity再次进行动态申请,因此,需要在我们编写的Activity里再次申请权限:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
            Log.d("进入:", "requestPermissions");
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
            Log.d("进入:", "requestPermissions");
        }

拍照按钮触发事件`

1.拍照按钮的点击事件如下:

mBtnUpload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //点击事件:进行拍照
                Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File photoFile=createImgFile();
                photoUri= Uri.fromFile(photoFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                startActivityForResult(intent,1);

            }
        });

2.上述“createImgFile()”函数的功能是自定义图片名,获取照片的file,具体代码如下:

/**
     * 自定义图片名,获取照片的file
     */
    private File createImgFile(){
        //确定文件名
        String fileName="img_"+new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())+".jpg";
        File dir;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            dir=Environment.getExternalStorageDirectory();
        }else{
            dir=getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        }
        File tempFile=new File(dir,fileName);
        try{
            if(tempFile.exists()){
                tempFile.delete();
            }
            tempFile.createNewFile();
        }catch (IOException e){
            e.printStackTrace();
        }
        //获取文件路径
        photoPath = tempFile.getAbsolutePath();
        return tempFile;
    }

3.由于上述代码采用了“startActivityForResult()”方法,因此在拍照完成后会调用“onActivityResult()”函数。我们重写该函数(以实现照片存储、添加到相册中的功能):

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode==RESULT_OK){
            switch (requestCode){
                case 1:
                    setImageBitmap();
                    galleryAddPic();
                    break;
                case 2:
                    //data中自带有返回的uri
                    photoUri=data.getData();
                    //获取照片路径
                    String[] filePathColumn={MediaStore.Audio.Media.DATA};
                    Cursor cursor=getContentResolver().query(photoUri,filePathColumn,null,null,null);
                    cursor.moveToFirst();
                    photoPath=cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
                    cursor.close();
                    //有了照片路径,之后就是压缩图片,和之前没有什么区别
                    setImageBitmap();
                    break;
            }
        }
    }

注:此处的“case 2”语句块用于从手机本地相册选取照片,由于代码类似,不再进行演示。
4.“setImageBitmap()”函数的功能是压缩我们刚刚拍到的图片,并将该图片展示在我们声明的“ImageView”控件中。具体代码如下:

/**
     * 压缩图片
     */
    private void setImageBitmap(){
        Log.d("Record", "进入压缩图片");
        //获取imageview的宽和高
        int targetWidth=photoImageView.getWidth();
        int targetHeight=photoImageView.getHeight();

        //根据图片路径,获取bitmap的宽和高
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(photoPath,options);
        int photoWidth=options.outWidth;
        int photoHeight=options.outHeight;
        Log.d("Record", "获取长和高:"+ photoHeight + "Width:" + photoWidth);

        //获取缩放比例
        int inSampleSize=1;
        if(photoWidth>targetWidth||photoHeight>targetHeight){
            int widthRatio=Math.round((float)photoWidth/targetWidth);
            int heightRatio=Math.round((float)photoHeight/targetHeight);
            inSampleSize=Math.min(widthRatio,heightRatio);
            Log.d("Record", "进入缩放比例");
        }

        //使用现在的options获取Bitmap
        options.inSampleSize=inSampleSize;
        options.inJustDecodeBounds=false;
        Bitmap bitmap=BitmapFactory.decodeFile(photoPath,options);
        photoImageView.setImageBitmap(bitmap);
        //调用转换函数,将ImageView文件转换为String类型数据,以便传输到云端
        String bitmapToString = putImageToShare(getApplicationContext(), photoImageView);
        mTvChange.setText(bitmapToString);
        //调用上传函数,将String类型数据传送到服务器
        UploadImage(getApplicationContext(), bitmapToString);
        Log.d("Record", "ToString:" + bitmapToString);
        Log.d("Record", "获取Bitmap");
    }

其中的“putImageToShare()”、“UploadImage()”方法作用分别是图片转换成String类型的数据、将该数据上传至服务器。如果不需要实现照片上传至服务器的功能,可以删除这两行代码。如果需要实现上传功能,可以看这篇文章:
Android平台实现图片传输到服务器并在服务器文件夹中重现(客户端程序+服务器端程序)

5.“galleryAddPic()”函数的功能是将我们刚刚拍到的照片添加到手机相册中,具体代码如下:

//将图片添加进手机相册
    private void galleryAddPic(){
        Intent mediaScanIntent=new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(photoUri);
        this.sendBroadcast(mediaScanIntent);
    }

后记

记录一些编程过程中踩到的坑:
1.在Android 10中,读写手机内存权限还需要进行额外的操作:
在“AndroidManifest”文件中添加语句:

android:requestLegacyExternalStorage="true"

否则ImageView控件无法显示我们的图片。
2.在Android 10中,执行上述代码时,调用相机会闪退。解决方法如下:
在对应Activity中添加语句:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy( builder.build() );
        }

参考文章:

https://blog.csdn.net/happy_fsyy/article/details/51986444
——————————————————————————
最后贴一下我的个人公众号:微信搜索“茶迁”或扫描下图。平时会更新一些编程相关的文章,欢迎大家关注~
茶迁

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Qt for Android可以通过Qt Multimedia模块来调用安卓手机摄像头实现拍照和录像功能。 首先,需要在.pro文件中添加multimedia模块的引用,即将`QT += multimedia`添加到.pro文件中。 接下来,创建一个QCamera对象,可以使用默认摄像头或指定摄像头。通过调用`QCameraInfo::defaultCamera()`可以获取默认摄像头的信息,或者使用`QCameraInfo::availableCameras()`获取所有可用摄像头列表。然后,调用`setCaptureMode()`方法来设置摄像头的捕获模式,可以选择使用`QCamera::CaptureStillImage`来拍照,或使用`QCamera::CaptureVideo`来录制视频。 如果需要显示摄像头的即时预览画面,可以创建一个QCameraViewfinder对象,并将其设置为QCamera的视图finder,然后将QCameraViewfinder设置为显示在窗口上。可以使用QGraphicsView或QWidget来显示摄像头的预览画面。 在拍照时,可以使用QCameraCaptureSession或直接使用QCamera的capture()方法来捕获静态图像。捕获的图像可以使用QCameraImageCapture类获取,并保存到本地文件中。 在录制视频时,可以使用QMediaRecorder来进行视频录制,首先创建一个QMediaRecorder对象,并使用setMedia()方法设置录制的媒体文件名和格式。然后,设置视频编码器、分辨率、比特率等参数,并调用record()方法开始录制,调用stop()方法停止录制。 最后,记得在AndroidManifest.xml文件中添加相应的权限,例如访问相机、录音和存储权限。 通过以上步骤,就可以在Qt for Android中成功调用手机摄像头实现拍照和录像功能了。 ### 回答2: 在Qt for Android开发中,要调用手机摄像头,可以使用Qt Multimedia模块中的QCamera类。 首先,需要在.pro文件中添加对Multimedia模块的依赖: ``` QT += multimedia ``` 然后,在代码中引入QCamera和QCameraViewfinder类: ``` #include <QCamera> #include <QCameraViewfinder> ``` 接下来,创建一个QCamera对象并设置使用后置摄像头: ``` QCamera* camera = new QCamera; camera->setCaptureMode(QCamera::CaptureStillImage); // 设置为拍照模式 camera->setCaptureMode(QCamera::CaptureVideo); // 设置为录像模式 QCameraViewfinder* viewfinder = new QCameraViewfinder; camera->setViewfinder(viewfinder); QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); foreach (const QCameraInfo& cameraInfo, cameras) { if (cameraInfo.position() == QCamera::BackFace) { // 后置摄像头 camera->setCamera(cameraInfo); // 设置为后置摄像头 break; } } ``` 然后,可以在需要调用摄像头的地方,调用QCamera的相关方法,比如开始预览、拍照或录像: ``` camera->start(); camera->searchAndLock(); camera->unlock(); camera->searchAndCapture(); ``` 最后,需要在界面上显示摄像头预览画面,可以将QCameraViewfinder设置为QWidget的子控件,并将其显示出来: ``` QVBoxLayout* layout = new QVBoxLayout; layout->addWidget(viewfinder); setLayout(layout); ``` 以上就是利用Qt for Android调用手机摄像头的基本步骤,开发者可以根据实际需求,进一步对摄像头功能进行扩展和定制。 ### 回答3: 在Qt中调用Android手机摄像头可以通过Qt Multimedia模块来实现。首先,确保已经正确配置了Qt for Android开发环境,并在.pro文件中添加了对Qt Multimedia模块的依赖,类似于:QT += multimedia。 接下来,创建一个Qt Quick界面来显示摄像头捕获的图像。可以使用Camera类型的对象来控制摄像头,并将摄像头的图像显示在Qt Quick界面上。 具体的步骤如下: 1. 在Qt Creator中创建一个新的Qt Quick项目。 2. 在qml文件中添加一个Item,用于显示摄像头图像,例如: Item { id: cameraView width: 640 height: 480 visible: camera.available anchors.centerIn: parent } 3. 在C++代码中创建一个Camera对象并连接到cameraView的source属性上: QCamera *camera = new QCamera(this); camera->setViewfinder(cameraView); camera->start(); 4. 在AndroidManifest.xml文件中添加相机权限,例如: <uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera"/> <uses-feature android:name="android.hardware.camera.autofocus"/> <uses-feature android:name="android.hardware.camera.flash"/> 5. 在运行项目之前,将生成的apk安装到Android手机上,并确保手机上有可用的摄像头。 通过以上步骤,你的Qt for Android应用程序现在可以调用Android手机摄像头并显示捕获的图像了。你还可以通过QCameraViewfinderSettings类来更改摄像头的设置,例如分辨率、帧率等。除了显示图像,你还可以使用QCamera类提供的其他函数来控制摄像头拍照、录像等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

保温杯拖把风扇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值