最近做到一个项目需要对图片的部分区域进行识别,所以需要手动框选图片的位置大小等信息,网上看了些demo,有些有BUG未解决,有些功能不完善,索性就自己花了点时间写了一个。
功能如下:
目前功能支持矩形区域的选择,并可以对矩形区域进行拖动、缩放、以及保存删除操作。基本上我要的功能都实现了。
原理
操作在一个自定义的QLabel中实现, 重写实现它的一些鼠标事件绘图事件等。计算好相应的位置值即可。
MyLabel.h
#pragma once
#include <QLabel>
/* 缩放方向 */
enum EmDirection
{
DIR_TOP = 0,
DIR_BOTTOM,
DIR_LEFT,
DIR_RIGHT,
DIR_LEFTTOP,
DIR_LEFTBOTTOM,
DIR_RIGHTTOP,
DIR_RIGHTBOTTOM,
DIR_MIDDLE,
DIR_NONE
};
#define EDGPADDING 5 //四周边缘可拉伸宽度
#define CORPADDING 6 //四角可拉伸宽度
#define MIN_WIDTH 5 //可拉伸的最小宽度
#define MIN_HEIGHT 5 //可拉伸的最小高度
#define POINT_WIDTH 6 //边缘9点的宽度
#define POINT_HEIGHT 6 //边缘9点的高度
#define EDGE_WIDTH 3 //边框的宽度
#define MIDDLELINE_WIDTH 2 //辅助线的宽度
#define DRAW_TEN_POINT //绘制十个点
#define DRAW_SUB_LINE //绘制辅助线
class QMenu;
class QAction;
class MyLabel : public QLabel
{
Q_OBJECT
public:
MyLabel(QWidget *parent = nullptr);
~MyLabel();
QRect getRoiRect() const; //获取已经圈选的框 外部调用
void setBackImage(const QImage &img); //设置背景图片 外部调用
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *ev);
void mouseMoveEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
void keyPressEvent(QKeyEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
private:
void initViewer(); //初始化
void saveROIImage(); //把ROI区域的图片存储下来
EmDirection region(const QPoint &point); //根据鼠标位置设置鼠标形状
void scaleRect(const QPoint &mousePoint); //缩放矩形
void paintRect(const QPoint &mousePoint); //绘制矩形
void moveRect(const QPoint &mousePoint); //移动矩形
private:
bool m_bPainterPressed; //是否正在绘制
bool m_bMovedPressed; //是否正在拖动
bool m_bScalePressed; //是否正在缩放大小
QPoint m_paintStartPoint; //绘制的初始位置
QPoint m_moveStartPoint; //拖动的初始位置
QRect m_roiRect; //绘制的ROI
EmDirection m_emCurDir; //拖动的方向
QImage m_backImage; //背景图
QMenu *m_pOptMenu;
QAction *m_pDelAction;
QAction *m_pSaveAction;
};
具体实现查阅代码,代码链接:https://download.csdn.net/download/qq_36131739/12248362
没有积分的可留邮箱,代码仅供参考学习。