700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > VS+Qt应用开发-Qt+Halcon显示图片 实现鼠标缩放 移动图片

VS+Qt应用开发-Qt+Halcon显示图片 实现鼠标缩放 移动图片

时间:2022-12-30 01:15:20

相关推荐

VS+Qt应用开发-Qt+Halcon显示图片 实现鼠标缩放 移动图片

VS+Qt应用开发-Qt+Halcon显示图片,实现鼠标缩放、移动图片

效果展示界面设计代码例程完整代码CMyLabel.hCMyLabel.cppBrowsePic.hBrowsePic.cpp 关键代码解释

关于显示图像以及前后浏览的功能请参照我的另一篇博客:

VS+Qt应用开发-实现从文件夹打开图片,前后浏览

关于控件提升请参照我的另一篇博客:

VS+Qt应用开发-控件提升-以Label为例

效果展示

动态展示

显示图像

鼠标滚轮缩放图像

鼠标按下拖动平移图像

实时显示坐标和灰度值

恢复图像

界面设计

在文章VS+Qt应用开发-实现从文件夹打开图片,前后浏览

的界面基础上进行以下增改:

添加一个Push Button,对象名设为btn_resetPic,用于恢复图片;添加一个Label,对象名设为label_status,用于实时显示坐标和灰度值;将label_show控件提升为CMyLabel类,用于接收鼠标事件。

代码例程

完整代码

首先贴上完整代码:

CMyLabel.h

#pragma once#include <QLabel>#include <QWheelEvent>#include <HalconCpp.h>using namespace Halcon;class CMyLabel : public QLabel{Q_OBJECTpublic:CMyLabel(QWidget *parent = Q_NULLPTR);~CMyLabel();//设置Halcon图像和Halcon窗口句柄,用户响应鼠标事件后实时更新图像void setHalconWnd(Hobject img, HTuple hHalconID, QLabel *label);//鼠标滚轮缩放事件void wheelEvent(QWheelEvent *ev);//鼠标按下事件void mousePressEvent(QMouseEvent *ev);//鼠标释放事件void mouseReleaseEvent(QMouseEvent *ev);//鼠标移动事件void mouseMoveEvent(QMouseEvent *ev);public:HTuple m_labelID;//Qt标签句柄HTuple m_hHalconID;//Halcon窗口句柄Hobject m_currentImg;//当前的图像//主界面显示坐标的标签QLabel *m_label;//鼠标按下的位置 HTuple m_tMouseDownRow;HTuple m_tMouseDownCol;bool m_bIsMove;//是否移动图像标识};

CMyLabel.cpp

#include "CMyLabel.h"//定义单步放大倍率#define ZOOMRATIO 2.0CMyLabel::CMyLabel(QWidget *parent): QLabel(parent){m_bIsMove = false;}CMyLabel::~CMyLabel(){}//设置Halcon图像和Halcon窗口句柄,用户响应鼠标事件后实时更新图像void CMyLabel::setHalconWnd(Hobject img, HTuple hHalconID, QLabel *label){m_hHalconID = hHalconID;m_currentImg = img;m_label = label;}//鼠标滚轮缩放事件,用于缩放图像void CMyLabel::wheelEvent(QWheelEvent *ev){double Zoom;//放大或缩小倍率HTuple mouseRow, mouseCol, Button;HTuple startRowBf, startColBf, endRowBf, endColBf, Ht, Wt, startRowAft, startColAft, endRowAft, endColAft;//滚轮前滑,放大if (ev->delta() > 0){Zoom = ZOOMRATIO;}else{Zoom = 1 / ZOOMRATIO;}//获取光标在原图上的位置,注意是原图坐标,不是Label下的坐标set_check("~give_error");Herror ret = get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button);set_check("give_error");//当光标不在Halcon窗口内时返回,否则会报错if (ret != H_MSG_TRUE){return;}//获取原图显示的部分,注意也是原图坐标get_part(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);//缩放前显示的图像宽高Ht = endRowBf - startRowBf;Wt = endColBf - startColBf;//普通版halcon能处理的图像最大尺寸是32K*32K。如果无限缩小原图像,导致显示的图像超出限制,则会造成程序崩溃if ((Ht * Wt < 20000 * 20000 || Zoom == ZOOMRATIO)){//计算缩放后的图像区域startRowAft = mouseRow - ((mouseRow - startRowBf) / Zoom);startColAft = mouseCol - ((mouseCol - startColBf) / Zoom);endRowAft = startRowAft + (Ht / Zoom);endColAft = startColAft + (Wt / Zoom);//如果放大过大,则返回if (endRowAft - startRowAft < 2){return;}if (m_hHalconID != NULL){//如果有图像,则先清空图像detach_background_from_window(m_hHalconID);}set_part(m_hHalconID, startRowAft, startColAft, endRowAft, endColAft);attach_background_to_window(m_currentImg, m_hHalconID);}}//鼠标按下事件void CMyLabel::mousePressEvent(QMouseEvent *ev){HTuple mouseRow, mouseCol, Button;set_check("~give_error");Herror ret = get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button);set_check("give_error");//当光标不在Halcon窗口内时返回,否则会报错if (ret != H_MSG_TRUE){return;}//鼠标按下时的行列坐标m_tMouseDownRow = mouseRow;m_tMouseDownCol = mouseCol;m_bIsMove = true;}//鼠标释放事件void CMyLabel::mouseReleaseEvent(QMouseEvent *ev){m_bIsMove = false;}//鼠标移动事件void CMyLabel::mouseMoveEvent(QMouseEvent *ev){HTuple startRowBf, startColBf, endRowBf, endColBf, mouseRow, mouseCol, Button;//获取当前鼠标在原图的位置set_check("~give_error");Herror ret=get_mposition(m_hHalconID, &mouseRow, &mouseCol, &Button);set_check("give_error");//当光标不在Halcon窗口内时返回,否则会报错if (ret != H_MSG_TRUE){return;}//鼠标按下并移动时,移动图像,否则只显示坐标if (m_bIsMove){//计算移动值double RowMove = mouseRow[0].D() - m_tMouseDownRow[0].D();double ColMove = mouseCol[0].D() - m_tMouseDownCol[0].D();//得到当前的窗口坐标get_part(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);//移动图像if (m_hHalconID != NULL){//如果有图像,则先清空图像detach_background_from_window(m_hHalconID);}set_part(m_hHalconID, startRowBf - RowMove, startColBf - ColMove, endRowBf - RowMove, endColBf - ColMove);attach_background_to_window(m_currentImg, m_hHalconID);}//获取灰度值HTuple pointGray;set_check("~give_error");ret = get_grayval(m_currentImg, mouseRow, mouseCol, &pointGray); set_check("give_error");//当光标不在Halcon窗口内时返回,否则会报错if (ret != H_MSG_TRUE){m_label->setText(QString::fromLocal8Bit("X坐标:- Y坐标:- 灰度值:-"));return;}//设置坐标m_label->setText(QString::fromLocal8Bit("X坐标:%1 Y坐标:%2 灰度值:%3").arg(mouseCol[0].D()).arg(mouseRow[0].D()).arg(pointGray[0].D()));}

BrowsePic.h

#pragma once#include <QtWidgets/QWidget>#include "ui_BrowsePic.h"#include <HalconCpp.h>#include <QToolBar>using namespace Halcon;#pragma execution_character_set("utf-8");class BrowsePic : public QWidget{Q_OBJECTpublic:BrowsePic(QWidget *parent = Q_NULLPTR);~BrowsePic();//初始化void init();//打开窗口void showImg();//窗体大小改变事件void resizeEvent(QResizeEvent *ev);public://显示图像的控件idHTuple m_hLabelID;//QLabel控件句柄HTuple m_hHalconID;//Halcon显示窗口句柄//原始图像的尺寸HTuple m_imgWidth, m_imgHeight;//图片路径列表HTuple m_imgFiles;//当前图像Hobject m_hCurrentImg;//当前图像的下标HTuple index;//是否等比缩放bool m_bIsEqualScale;//是否居中显示bool m_bIsShowCenter;//缩放后的图像Hobject m_hResizedImg;//缩放系数HTuple m_hvScaledRate;//缩放后图像的大小HTuple m_scaledHeight, m_scaledWidth;QToolBar *m_toolBar;public slots://打开图片void on_btn_openPic_clicked();//浏览前一张void on_btn_prePic_clicked();//浏览后一张void on_btn_nextPic_clicked();//恢复图片void on_btn_resetPic_clicked();//等比缩放复选框状态改变void on_checkBox_equalScale_stateChanged(int);//居中显示复选框状态改变void on_checkBox_showCenter_stateChanged(int);private:Ui::BrowsePicClass ui;};

BrowsePic.cpp

#include "BrowsePic.h"#include <QFileDialog>#include <QFileInfo>#include <QLabel>BrowsePic::BrowsePic(QWidget *parent): QWidget(parent){ui.setupUi(this);//初始化 init();}BrowsePic::~BrowsePic(){}//初始化void BrowsePic::init(){//设置halcon的文件路径为utf8,解决中文乱码set_system("filename_encoding", "utf8");//生成空图像gen_empty_obj(&m_hCurrentImg);//获取图像显示控件的句柄m_hHalconID = NULL;m_hLabelID = (Hlong)ui.label_show->winId();m_bIsEqualScale = false;m_bIsShowCenter = true;ui.checkBox_equalScale->setChecked(m_bIsEqualScale);ui.checkBox_showCenter->setChecked(m_bIsShowCenter);ui.checkBox_showCenter->setEnabled(false);}//打开窗口void BrowsePic::showImg(){//判断图像是否为空Hlong isEqual;Hobject emptyObj;gen_empty_obj(&emptyObj);test_equal_obj(emptyObj, m_hCurrentImg, &isEqual);if (isEqual){return;}if (m_hHalconID != NULL){//如果有图像,则先清空图像detach_background_from_window(m_hHalconID);}else{//打开窗口open_window(0, 0, ui.label_show->width(), ui.label_show->height(), m_hLabelID, "visible", "", &m_hHalconID);}ui.label_show->setHalconWnd(m_hCurrentImg, m_hHalconID, ui.label_status);get_image_size(m_hCurrentImg, &m_imgWidth, &m_imgHeight);//判断是否等比缩放if (m_bIsEqualScale){//获取缩放系数tuple_min2(1.0 * ui.label_show->width() / m_imgWidth, 1.0 * ui.label_show->height() / m_imgHeight, &m_hvScaledRate);//进行图像缩放zoom_image_factor(m_hCurrentImg, &m_hResizedImg, m_hvScaledRate, m_hvScaledRate, "constant");get_image_size(m_hResizedImg, &m_scaledWidth, &m_scaledHeight);set_window_extents(m_hHalconID, 0, 0, m_scaledWidth, m_scaledHeight);if (m_bIsShowCenter){if (1.0*ui.label_show->width() / m_imgWidth < 1.0*ui.label_show->height() / m_imgHeight){set_window_extents(m_hHalconID, ui.label_show->height() / 2.0 - m_scaledHeight / 2.0, 0, ui.label_show->width(), m_scaledHeight);}else{set_window_extents(m_hHalconID, 0, ui.label_show->width() / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, ui.label_show->height());}}}else{set_window_extents(m_hHalconID, 0, 0, ui.label_show->width(), ui.label_show->height());}set_part(m_hHalconID, 0, 0, m_imgHeight - 1, m_imgWidth - 1);attach_background_to_window(m_hCurrentImg, m_hHalconID);}//窗体大小改变事件void BrowsePic::resizeEvent(QResizeEvent *ev){if (m_hHalconID != NULL){//防止窗口闪烁set_system("flush_graphic","false");showImg();set_system("flush_graphic", "true");detach_background_from_window(m_hHalconID);attach_background_to_window(m_hCurrentImg, m_hHalconID);}}//打开图片void BrowsePic::on_btn_openPic_clicked(){//打开选择文件对话框,选择文件QString qtFilePath = QFileDialog::getOpenFileName(this, "选择图片", "./", "图像文件(*.jpg *.png *.bmp *.tif)");if (qtFilePath.isEmpty()){return;}QFileInfo fileInfo(qtFilePath);qtFilePath.replace("/", "\\");QString hPath = fileInfo.path().replace("/", "\\");//由halcon算子获取选中的文件夹中的所有文件list_files(hPath.toStdString().c_str(), HTuple("files").Append("follow_links"), &m_imgFiles);//筛选符合图片格式的文件tuple_regexp_select(m_imgFiles, HTuple("\\.(jpg|png|bmp|tif)$").Append("ignore_case"), &m_imgFiles);//找到选择的文件tuple_find(m_imgFiles, qtFilePath.toStdString().c_str(), &index);//读取图像read_image(&m_hCurrentImg, HTuple(m_imgFiles[index]));showImg();}//浏览前一张void BrowsePic::on_btn_prePic_clicked(){if (index.Num()>0&&index[0].I() > 0){index[0] = index[0].I() - 1;read_image(&m_hCurrentImg, HTuple(m_imgFiles[index]));showImg();}}//浏览后一张void BrowsePic::on_btn_nextPic_clicked(){if (index.Num()>0 && index[0].I() < m_imgFiles.Num() - 1){index[0] = index[0].I() + 1;read_image(&m_hCurrentImg, HTuple(m_imgFiles[index]));showImg();}}//恢复图片void BrowsePic::on_btn_resetPic_clicked(){showImg();}//等比缩放复选框状态改变void BrowsePic::on_checkBox_equalScale_stateChanged(int state){ui.checkBox_showCenter->setEnabled(state);m_bIsEqualScale = state;showImg();}//居中显示复选框状态改变void BrowsePic::on_checkBox_showCenter_stateChanged(int state){m_bIsShowCenter = state;showImg();}

关键代码解释

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。