记一次基于QT的图片操作处理优化思路(包括在图上放大缩小,截图,画线,取值等)

文章目录


0 引入

最近使用QT对于图像处理,网上写的不够详细,通过自己的尝试以及网上的资料最终做出的效果还行,话不多说,直接上图


右边工具条从上到下的功能:

1、显示十字线,用来做图片位置校准用的;

2、还原最初的设置;

3、设置ROI区域;

4、还原之前的设置;

5、放大缩小;

6、图上画水平直线、和垂直直线;

7、实时显示图片坐标值和灰度值;

8、显示图片的一条灰度值;

9、保存图片设置

最小面的是16灰度值调节设置(这个还是比较有意思的)

1、思路

1、第一条就是,所有绘画的操作都需要在paintEvent进行,这是Qt官网建议的;

2、鼠标事件我是重构了event函数(当然也可以重构mouse相关的);

3、resizeEvent和update都会触发paintEVent操作,所以需要放大和整个界面需要重构这个函数;

4、上述的有些操作需要再加一层图片操作,我这里大致有三层,只不过背景都是透明,看起来在一层操作;

每个操作我是进行了一个枚举,包含上述的9个操作,然后再event中根据类型判断操作;其实每个一操作,在网上应该能找到相应的代码,在这里不赘述;


2、部分代码示例

1.引入库

操作枚举:

c 复制代码
enum OPERATE{
    OROI = 0,
    ODrag,
    OReset,
    OAnalysis,
    OPrimit,
    OLine,
    OPoint,
    OStop
};

这里举个event重构函数

c 复制代码
enum OPERATE{
    QMouseEvent *mouse = dynamic_cast<QMouseEvent*>(event);
    switch (mOperate) {
    case OAnalysis:{
        if(event->type() == QEvent::MouseButtonPress){
            if (mouse->buttons() & Qt::LeftButton)
            {
                mMove = mouse->pos();
                update();
            }
        }
        break;
    }
    case ODrag:{
        static bool press = false;
        static QPoint predot;
        if(event->type() == QEvent::MouseButtonPress){
            if(mouse->button() == Qt::LeftButton && mPaintRect.contains(mouse->pos())){
                press = true;
                QApplication::setOverrideCursor(Qt::OpenHandCursor);
                predot = mouse->pos();
            }
        }else if(event->type() == QEvent::MouseButtonRelease){
            if(mouse->button() == Qt::LeftButton && press){
                press = false;
                QApplication::setOverrideCursor(Qt::ArrowCursor);
            }
        }
        if(event->type() == QEvent::MouseMove){
            if(press){
                offset.setX(mouse->x() - predot.x());
                offset.setY(mouse->y() - predot.y());
                predot = mouse->pos();
                mAction = ACTION::MoveOnly;
                this->update();
            }
        }
        break;
    }
    case OLine:{
        static bool press = false;
        if(event->type() == QEvent::MouseButtonPress){
            if(mouse->button() == Qt::LeftButton && mPaintRect.contains(mouse->pos())){
                QPainter drawp(&mpixLine);
                drawp.setCompositionMode(QPainter::CompositionMode_SourceOver);
                drawp.drawPixmap(QPoint(0,0),mMarkpix);

                press = true;
                QApplication::setOverrideCursor(Qt::CrossCursor);
                startPoint = mouse->pos();
            }
        }else if(event->type() == QEvent::MouseButtonRelease){
            if(mouse->button() == Qt::LeftButton && press){
                press = false;
                QApplication::setOverrideCursor(Qt::ArrowCursor);
                //画直线需要水平线和竖直线
                if(qAbs(MovetPoint.x()-startPoint.x()) <= qAbs(MovetPoint.y()-startPoint.y()))
                { MovetPoint.setX(startPoint.x());}
                else  MovetPoint.setY(startPoint.y());
                this->update();
            }
        }
        if(event->type() == QEvent::MouseMove){
            if(press){
                MovetPoint = mouse->pos();
                this->update();
            }
        }
        break;
    }
    case OPoint:{
        if(event->type() == QEvent::MouseMove ){
            mMove = mouse->pos();
            QString str = "(n,n):0000";
            if(mPaintRect.contains(mMove)){
                int py = mMove.y()*mYfactor;
                int px = mMove.x()*mXfactor;
                ushort value = mCVImage.at<ushort>(py,px);
                str = QString("(%1,%2):%3").arg(QString::number(px),
                                                QString::number(py),QString::number(value));
            }
            mpPosform->setContent(str);
            mpPosform->move(mMove.x()+10,mMove.y()-5);
            //this->update();
        }
        break;
    }
    default:
        break;
    }
    return QWidget::event(event);
};

其他函数暂时不展示。

3、总结

通过自己亲自实现上述功能,对于QPainter的使用已经在一个图片上实现多层操作有很大的收获。


相关推荐
ClickHouseDB10 小时前
ClickHouse Cloud 与 Snowflake 实时性价比对比:CostBench 测试中的 412 倍差距来
运维·数据库·系统架构
第九序言T10 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
m0_6399069410 小时前
Redis入门|五种数据结构、使用场景、持久化RDB&AOF
数据结构·数据库·redis
时间售卖铺11 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw11 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
龙亘川11 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人11 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
Raas10012 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
数智园区合作社12 小时前
问数平台怎么把同一个指标锁成一个数
大数据·数据库·人工智能·ai
lbb 小魔仙13 小时前
Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程
数据库·人工智能·prometheus·时序数据库