使用Halcon库,在Qt界面打开显示图片,可实现多次打开不同图片

862 阅读1分钟

在Qt界面打开图片,有两种方式:

方法(1)Halcon读取文件,取出图像的buffer,然后转换成qt的图像格式QImage或者QPixmap,再通过qt的控件显示。

QImage img = HObject转换而来;
if (img.isNull())
{
     ui->label_pic->setPixmap(QPixmap(":/res/icons/picture.png"));
}
else
{
     ui->label_pic->setPixmap(QPixmap::fromImage(img).scaled(ui->label_pic->width(), \
ui->label_pic->height(), Qt::KeepAspectRatio));
}

方法(2)Halcon读取文件,获得graphicsView或者QLabel控件句柄,绑定它们,再显示。

本篇着重写第(2)种方法。

头文件如下:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    void showPic(const QString &path);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

源文件如下:

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>

#ifndef __APPLE__
#include "HalconCpp.h"
#else
#ifndef HC_LARGE_IMAGES
#include <HALCONCpp/HalconCpp.h>
#else
#include <HALCONCppxl/HalconCpp.h>
#endif
#endif

using namespace HalconCpp;

#ifdef __APPLE__
#define UINT unsigned int
#endif

Widget::Widget(QWidget *parent)
    : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    QFileDialog *fileDlg = new QFileDialog(this);
    fileDlg->setWindowTitle(tr("打开图片"));

    QStringList qstrFilters;
    qstrFilters << "Images (*.png *.bmp *.jpg)";
    qstrFilters << "All files(*)";
    fileDlg->setNameFilters(qstrFilters);            //设置文件过滤器
    fileDlg->setFileMode(QFileDialog::ExistingFile); //设置选择单文件,如果是多个文件就写成ExistingFiles
    fileDlg->setAcceptMode(QFileDialog::AcceptOpen);

    if (fileDlg->exec() == QDialog::Accepted)
    {
        QStringList strPathList = fileDlg->selectedFiles();
        if (strPathList.count() > 0)
        {
            showPic(strPathList.at(0));
        }
    }

    fileDlg->close();
    delete fileDlg;
    fileDlg = nullptr;
}

void Widget::showPic(const QString &path)
{
    HObject ho_Image;
    HTuple hv_Width, hv_Height, hv_WindowHandle1, hv_WindowHandle2;

    std::string p1 = path.toStdString();
    const char *p2 = p1.c_str();

    try
    {
        //打开图片
        ReadImage(&ho_Image, p2);                      //读取图片
        GetImageSize(ho_Image, &hv_Width, &hv_Height); //获得图像宽高

        std::cout << hv_Width.I() << std::endl;
        std::cout << hv_Height.I() << std::endl;

        //清除缓存
        if (HDevWindowStack::IsOpen())
        {
            CloseWindow(HDevWindowStack::Pop()); //这段话很重要,否则无法连续打开图像显示,仅仅固定显示第一次打开的图
        }

        if (HDevWindowStack::IsOpen())
        {
            CloseWindow(HDevWindowStack::Pop()); //这段话很重要,否则无法连续打开图像显示,仅仅固定显示第一次打开的图
        }

        //显示在graphicsView控件
        Hlong wndView = (Hlong)ui->graphicsView->winId();                                                                   //获得graphicsView控件句柄
        OpenWindow(0, 0, ui->graphicsView->width(), ui->graphicsView->height(), wndView, "visible", "", &hv_WindowHandle1); //打开窗口
        HDevWindowStack::Push(hv_WindowHandle1);                                                                            //这段话很重要,否则无法连续打开图像显示
        SetPart(hv_WindowHandle1, 0, 0, hv_Height, hv_Width);                                                               //自适应窗口
        DispObj(ho_Image, hv_WindowHandle1);                                                                                //graphicsView控件显示

        //显示在QLabel控件
        Hlong wndLabel = (Hlong)ui->label_pic->winId();                                                                //获得Lable控件句柄
        OpenWindow(0, 0, ui->label_pic->width(), ui->label_pic->height(), wndLabel, "visible", "", &hv_WindowHandle2); //打开窗口
        HDevWindowStack::Push(hv_WindowHandle2);                                                                       //这段话很重要,否则无法连续打开图像显示
        SetPart(hv_WindowHandle2, 0, 0, hv_Height, hv_Width);                                                          //自适应窗口
        DispObj(ho_Image, hv_WindowHandle2);                                                                           //label显示
    }
    catch (...)
    {
        std::cout << "err" << std::endl;
    }
}

不需要依赖动态库文件hcanvas.dll,只需要halcon.dll和halconcpp.dll这两个即可。

 

 

---

姊妹篇:

《使用Halcon库,在MFC界面打开显示图片,可实现多次打开不同图片》

libaineu2004.blog.csdn.net/article/det…