Qt 之 Camera 相机拍照并截图实现

背景

项目中,用到了拍照并截图,上传图片去后端拿题库答案,刚开始的实现是从屏幕中截图,然后保存成图片再上传,后来发现错了,因为是相当于屏幕截图,而实际上应该是拿相机拍照的图片做裁剪,来做后端的图片。项目中用到的是qml来实现。

类说明

window下相关类及使用

QCamera类
QCamera类是直接对应摄像头的类,包括如下方法:
1、QCamera()
创建摄像头类对象实例。

2、setViewfinder(viewfinder)
设置取景器,取景器就是将图像实时在屏幕显示,就跟相机的屏幕一样,参数是取景器类的实例对象。

3、setViewfinderSettings(viewFinderSettings)
设置取景器相关参数如分辨率等,请见QCameraViewfinderSettings类的介绍。

4、setCaptureMode(mode)
设置捕获图像(拍照)的保存模式,参数mode类型为枚举类型QCamera.CaptureModes,包括如下取值:

※ CaptureViewfinder:相机仅配置为显示取景器
※ CaptureStillImage:相机配置为静态帧捕获
※ CaptureVideo:相机配置为视频捕获

以上三个值可以通过or操作组合起来使用,经老猿验证,如果是拍照以上三个值都支持,CaptureVideo在windows系列操作系统下不支持。

5、start()打开相机
相机打开后取景器就能显示镜头范围内的内容。

6、stop()关闭相机
关闭相机后,取景器不再显示视频。

QCameraViewfinderSettings类
QCameraViewfinderSettings类是专门用于设置取景器参数的,常用的设置方法(读取方法名去掉set后首字母改为小写就可以了)如下:
1、setResolution(width,height)
以像素为单位设置取景器的分辨率。

2、setPixelAspectRatio(int horizontal, int vertical)
设置取景器的纵横比

3、setMinimumFrameRate(qreal rate)
设置取景器的最小帧速率(以每秒帧数为单位)

4、setMaximumFrameRate(qreal rate)
设置取景器的最大帧速率(以每秒帧数为单位)

5、setPixelFormat(QVideoFrame.PixelFormat format)
设置取景器图像的像素格式,即在内存中的存放格式(或编码方式),其类型为枚举类型enum QVideoFrame.PixelFormat

QCameraViewfinder类
QCameraViewfinder类是取景器对应类,这个类主要的方法就是构造方法,带一个参数指向取景器放置的父对象

QCameraImageCapture类
QCameraImageCapture是用于捕获图像的,主要有如下方法:
1、setCaptureDestination(CaptureDestinations destination)
setCaptureDestination方法设置捕获的图像是输出到文件还是在内存中缓存,参数destination是枚举类型CaptureDestinations ,有如下2个取值:
*※ CaptureToFile:对应值为 1,表示输出到文件
*※ CaptureToBuffer:,对应值为2,表示输出到缓存,可以在缓存中进一步处理
2、capture( QString filename )
capture从当前视频中捕获一帧作为图像保存,保存到参数指定的文件中。

常用代码:

查询和设置摄像头分辨率的API
QCamera::supportedViewfinderResolutions()
QCamera::setViewfinderSettings()
设置摄像头帧率、比例、分辨率、格式的类:QCameraViewfinderSettings

//打印相机支持的分辨率和帧率
for(int i=0;i< m_camera->supportedViewfinderResolutions().length();i++)
       qDebug() << "resolution " << m_camera->supportedViewfinderResolutions().at(i);

for(int i=0;i< m_camera->supportedViewfinderFrameRateRanges().length();i++)
        qDebug() << "framerate" << m_camera->supportedViewfinderFrameRateRanges().at(i).maximumFrameRate << m_camera->supportedViewfinderFrameRateRanges().at(i).minimumFrameRate;

//设置相机预览的分辨率
    QCameraViewfinderSettings set;
    set.setResolution(1280, 720);
    m_camera->setViewfinderSettings(set);

linux下相关类及使用

Camera类
VideoOutput类 用法基本等同于windows
常用代码:

	//打印支持的分辨率和帧率
	console.log("camera.supportedViewfinderFrameRateRanges()")
    var cl = camera.supportedViewfinderFrameRateRanges();
    for(var i = 0;i < cl.length;i++){
       console.log(cl[i].minimumFrameRate,cl[i].maximumFrameRate)
   }
 
   console.log("camera.supportedViewfinderResolutions()")
   var cl2 = camera.supportedViewfinderResolutions();
   for(var j = 0;j < cl2.length;j++){
      console.log(cl2[j].width,cl2[j].height)
   }
Camera {
        id: camera
        deviceId:QtMultimedia.availableCameras[0].deviceId
        captureMode: Camera.CaptureStillImage
        imageCapture {
            id:imgCapture
            onImageCaptured: {
            }
            onImageSaved:
            {
            }
        }
    }
    
{
   //测试分辨率
   //camera.viewfinder.resolution = Qt.size(2592, 1296);
   //camera.viewfinder.resolution = Qt.size(3264, 2448);
}

    VideoOutput {
        id: viewfinder
        anchors.fill: parent
        source: camera
        //autoOrientation: true
        orientation: 360
        MouseArea
        {
            anchors.fill: parent
            onClicked:
            {
            	//默认用法
            	//camera.imageCapture.capture()
            	//指定相机拍照后的路径
                camera.imageCapture.captureToLocation(filepath)
                var imagePath = filepath+".jpg";
            }
        }
    }

//videoOutput取景框的实际内容大小通过下面获得

 viewfinder.contentRect.width
 viewfinder.contentRect.height

使用注意事项

查询和设置摄像头分辨率时,需要在摄像头启动后调用,
即在调用QCamera::start()后,
可以使用QCamera::stateChanged(QCamera::State state)信号,
如果收到摄像头状态为QCamera::ActiveState后,再调用上述API

另外付:图片的裁剪实现

clipImage(const QString &fileName, const QString &newFilename,
                            const QRect rect, const int parewidth, const int pareheight)
{
    QImage img;
    if(!img.load(fileName)){
        return false;
    }

    int width = img.width();
    int height = img.height();

    int x = rect.x()*width/parewidth;
    int y = rect.y()*height/pareheight;
    int w = rect.width()*width/parewidth;
    int h = rect.height()*height/pareheight;

    qDebug() << rect << parewidth << pareheight;
    qDebug() << width << height << x<<y<<w<<h;

    QImage pimg = img.copy(x, y, w, h);
    bool b = pimg.save(newFilename);
    return  true;
}

另有截图实现,改天上传之csdn

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Qt中使用Android设备的相机进行拍照可以通过调用Android提供的相机API实现。首先,需要在.pro文件中添加相机和权限相关的配置: ``` QT += androidextras ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android ``` 然后,在AndroidManifest.xml文件中添加相机权限: ``` <uses-permission android:name="android.permission.CAMERA"/> ``` 接下来,创建一个Qt Android应用程序的C++类,例如CameraController,用于处理与相机相关的逻辑。在该类中,可以使用QAndroidJniObject类来调用相机API,如下所示: ```cpp #include <QAndroidJniObject> #include <QtAndroid> class CameraController : public QObject { Q_OBJECT public: Q_INVOKABLE void takePhoto() { QAndroidJniObject intent("android/content/Intent"); QAndroidJniObject MediaStore_Images_Media = QAndroidJniObject::getStaticObjectField( "android/provider/MediaStore$Images$Media", "EXTERNAL_CONTENT_URI", "Landroid/net/Uri;"); QAndroidJniObject action = QAndroidJniObject::getStaticObjectField( "android/provider/MediaStore$ACTION_IMAGE_CAPTURE", "Ljava/lang/String;"); intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", action.object<jstring>()); QtAndroid::startActivity(intent, 101, nullptr); } }; ``` 在Qt QML界面中,首先需要导入CameraController类,并创建一个CameraController对象。然后,在拍照按钮的点击事件中,可以调用CameraController的takePhoto方法来启动相机拍照: ```qml import QtQuick 2.0 import QtAndroidExtras 1.0 Item { width: 200 height: 200 CameraContoller { id: controller } Rectangle { width: parent.width height: parent.height color: "gray" MouseArea { anchors.fill: parent onClicked: { controller.takePhoto() } } } } ``` 以上是使用Qt实现在Android设备上调用相机拍照的简单示例。在实际应用中,还可以添加回调函数来处理拍照结果,并对相机API进行更多的配置和使用。 ### 回答2: 在Qt中,可以使用Android提供的Camera类来调用相机拍照。 首先,在Qt的工程文件(.pro文件)中添加Android权限声明,以便访问相机功能。可以添加以下代码: ```shell android { ... # 添加相机功能的权限声明 android:permission="android.permission.CAMERA" } ``` 然后,在Qt中创建一个按钮,用于触发拍照操作。可以使用QPushButton类,并在按钮的点击事件触发时调用拍照的函数。可以使用以下代码: ```c++ #include <QCamera> #include <QCameraImageCapture> ... QPushButton *button = new QPushButton("拍照", this); connect(button, &QPushButton::clicked, this, &MyClass::takePhoto); ... void MyClass::takePhoto() { // 创建相机对象 QCamera *camera = new QCamera(this); camera->setCaptureMode(QCamera::CaptureStillImage); // 创建像捕获对象 QCameraImageCapture *imageCapture = new QCameraImageCapture(camera); camera->setCaptureDestination(QCameraImageCapture::CaptureToFile); // 设置拍照保存路径 QString fileName = "路径/文件名.jpg"; imageCapture->setCaptureDestination(fileName); // 开始拍照 camera->start(); imageCapture->capture(); } ``` 上述代码中,首先创建相机对象和像捕获对象。然后设置拍照保存的路径,即将片保存到指定的路径和文件名中。最后,开始相机预览并调用`capture()`函数进行拍照。 通过以上步骤,就可以在Qt中使用Qt的API来调用Android系统的相机功能,实现拍照操作。当然,为了使用该功能,相应的权限要在工程文件中进行声明。 ### 回答3: 要在Qt实现安卓调用相机拍照,可以按照以下步骤进行操作。 首先,需要在项目的.pro文件中添加以下模块导入语句: ```ruby QT += androidextras ``` 然后,在Qt的主代码文件中引入相关模块: ```cpp #include <QtAndroidExtras> #include <QAndroidJniEnvironment> #include <QAndroidJniObject> ``` 接下来,可以通过如下代码来实现调用相机拍照的功能: ```cpp void invokeCamera() { QAndroidJniObject intent("android/content/Intent"); QAndroidJniObject action = QAndroidJniObject::getStaticObjectField( "android/provider/MediaStore", "ACTION_IMAGE_CAPTURE", "Ljava/lang/String;" ); intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", action.object<jstring>()); QtAndroid::startActivity(intent.object<jobject>(), 101, this); } ``` 以上代码创建一个Intent对象,并设置其action为ACTION_IMAGE_CAPTURE(拍照动作)。接下来,通过QtAndroid::startActivity函数来启动拍照活动,其中101是请求码,用于识别结果。 最后,在Qt的主代码文件中重写onActivityResult函数来处理拍照结果: ```cpp void YourClass::onActivityResult(int requestCode, int resultCode, const QAndroidJniObject &data) { if (requestCode == 101 && resultCode == -1) { // 获取拍照结果 QAndroidJniObject uri = data.callObjectMethod( "getData", "()Landroid/net/Uri;"); // 处理uri,例如显示照片 } } ``` 以上代码判断请求码和结果码是否匹配,如果拍照成功,则通过getData方法获取照片URI,可以将其用于进一步处理,比如显示照片。 需要注意的是,以上代码只适用于Qt for Android平台,并且需要在AndroidManifest.xml文件中添加拍照权限的声明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值