Qt纯实现图片处理工具:支持多形态绘制、自适应缩放与背景图功能
Qt实现的包含图片显示功能、自适应缩放、背景图片、画roi工具。 不依赖其他库纯Qt实现。 在图片上可以画矩形、矩形旋转、圆形、同心圆、多边形、直线、卡尺、锚点、清空。 源码 使用Qt5.6.1_MinGW、Qt5.15.1_MinGW、Qt5.15.1_msvc编译通过其他版本请自行尝试。在图像处理工具开发中经常需要实现灵活的ROI标注功能。最近用Qt搓了个轻量级解决方案核心代码不到2000行就实现了九种图形标注。最爽的是不依赖OpenCV等第三方库直接继承QGraphicsView就能玩转各种骚操作。先看自适应缩放的核心实现这里有个小技巧void ImageView::wheelEvent(QWheelEvent* event) { if(event-angleDelta().y() 0) scale(1.2, 1.2); // 滚轮放大 else scale(1/1.2, 1/1.2); // 滚轮缩小 } void ImageView::resizeEvent(QResizeEvent* event) { fitInView(sceneRect(), Qt::KeepAspectRatio); // 窗口缩放时自适应 }这样写的好处是既支持主动缩放又保持宽高比记得要在构造函数里设置setRenderHint(QPainter::SmoothPixmapTransform)让缩放更顺滑。背景图片处理更简单粗暴直接搞个全屏矩形void ImageScene::setBackgroundImage(const QPixmap pixmap) { clearBackground(); m_bgItem addPixmap(pixmap); m_bgItem-setZValue(-1); // 确保在最底层 }重点聊聊旋转矩形的实现这里我踩过的坑值得一说。普通矩形用QRectF就能搞定但旋转时需要自己计算四个顶点QRectF baseRect QRectF(startPoint, endPoint).normalized(); QPolygonF rotatedRect; QTransform transform; transform.rotate(angle_, startPoint.x(), startPoint.y()); // 绕起点旋转 rotatedRect transform.mapToPolygon(baseRect.toRect());这里用QTransform做旋转变换比手动计算坐标省事多了。记得要处理旋转后的碰撞检测可以用QGraphicsPolygonItem代替普通的矩形Item。Qt实现的包含图片显示功能、自适应缩放、背景图片、画roi工具。 不依赖其他库纯Qt实现。 在图片上可以画矩形、矩形旋转、圆形、同心圆、多边形、直线、卡尺、锚点、清空。 源码 使用Qt5.6.1_MinGW、Qt5.15.1_MinGW、Qt5.15.1_msvc编译通过其他版本请自行尝试。同心圆的实现更有意思我直接在鼠标移动事件里动态更新void ImageView::mouseMoveEvent(QMouseEvent* event) { if(mode_ CONCENTRIC_CIRCLE) { QPointF pos mapToScene(event-pos()); double radius QLineF(centerPoint_, pos).length(); outerCircle-setRect(centerPoint_.x()-radius, centerPoint_.y()-radius, radius*2, radius*2); innerCircle-setRect(centerPoint_.x()-radius/2, centerPoint_.y()-radius/2, radius, radius); } }这里维护两个QGraphicsEllipseItem外圆半径实时跟随鼠标位置内圆固定为一半比例。卡尺工具是当之无愧的MVP用QPainterPath画出刻度效果QPainterPath path; path.moveTo(start); path.lineTo(end); // 添加刻度线 for(int i0; i10; i){ QPointF pos start (end - start)*i/10; path.addPath(createTickMark(pos, angle)); // 生成单个刻度 }createTickMark函数负责计算垂直方向的短线段配合旋转角度生成测量刻度。清空功能别直接用scene-clear()会误删背景图。我这样处理void ImageScene::clearAllROI() { foreach(QGraphicsItem* item, items()){ if(item ! m_bgItem item-zValue() 0) removeItem(item); } }用zValue区分背景和ROI项妈妈再也不用担心误删背景了。这个方案在5.6到5.15的Qt版本都能跑实测内存占用相当友好。想要更炫的效果可以自己继承QGraphicsItem实现paint()方法用QPainter玩点渐变填充或者阴影效果。源码里还藏了个彩蛋——按Ctrl滚轮能横向滚动试试看
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2435353.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!