将命令行参数转换为Qimage

时间:2016-12-01 20:41:34

标签: c++ qt qimage

这不是最令人烦恼的解析问题,因为执行以下操作也会导致链接器错误,尽管没有歧义:

QImage baseline("C:\img1.png");
QImage test_image("C:\img1.png");

我的应用程序获得2个命令行参数,这些参数是2个不同图像的路径。

我想将它们转换为QImage,因此我可以使用Qt提供的==运算符对它们进行比较。

我尝试了以下方法来解决这个问题,但每次都会遇到链接器问题:

尝试1:

    QImage baseline(argv[1]);
    QImage test_image(argv[2]);

尝试2(首先转换为Qstring):

    QString base_path = QString::fromStdString(argv[1]);
    QString test_path = QString::fromStdString(argv[2]);
    QDir baseline(base_path);
    QDir test_image(test_path);

我认为这与没有包含正确的库有关,因为如果我只是执行以下操作,程序将编译并链接正常:

    Qimage test_image();

已经看过下面的帖子,遗憾的是在我的情况下它没有用处: Constructing QImage from unsigned char* data

有关可能导致链接器错误的任何想法?我怀疑他们会非常有帮助,但我会在这里留下链接器错误消息:

 Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "__declspec(dllimport) public: __thiscall QString::~QString(void)" (__imp_??1QString@@QAE@XZ) referenced in function _main image_compare_executable c:\Users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\image_compare_executable\image_compare_executable.obj 

1 Error LNK2019 unresolved external symbol "__declspec(dllimport) public:  static class QString __cdecl QString::fromStdString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (__imp_?fromStdString@QString@@SA?AV1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main image_compare_executable c:\Users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\image_compare_executable\image_compare_executable.obj 

1 Error LNK1120 2 unresolved externals image_compare_executable c:\users\gela8178\documents\visual studio 2015\Projects\image_compare_executable\Debug\image_compare_executable.exe 1

包含导致链接器问题的代码的相关片段:

#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <QtGui/QtGui>

using namespace cv;

int main(int argc, char* argv[])
{
// Check the number of parameters
if (argc < 3) {
    std::cerr << "Error: " << argv[0] << " : " << "Missing arguments" << std::endl;
    return 1;
}
std::cout << "Baseline: " << argv[1] << "\n" << "Test Image: " << argv[2] << std::endl;

QImage baseline(QString(argv[1]));
QImage test_image(QString(argv[2]));

if (baseline == test_image)
{
    std::cout << "Algorithm: Mem Compare" << "\n" << "Result: = Pass" << std::endl;
}
else
{
    std::cout << "Algorithm: Mem Compare" << "\n" << "Result: = Fail" << std::endl;
}
std::cout << "--------------------------------------------------------" << std::endl;

// ***************************************************************************** //

//Run MSSIM and output tuple
Mat i1 = imread(argv[1]);
Mat i2 = imread(argv[2]);

Scalar min_ssim = getMSSIM(i1, i2);
double R = min_ssim[0];
double G = min_ssim[1];
double B = min_ssim[2];

std::cout << "Algorithm: MSSIM" << "\n" << "Result: " << "(" << R << ", " << G << ", " << B << ")" << std::endl;

std::cout << "--------------------------------------------------------" << std::endl;

return 0;
}

SOLUTION:

查看QImage构造函数here,获取QString的唯一实例将其作为const reference

QImage(const QString &fileName, const char *format = Q_NULLPTR)

执行以下操作

    QImage baseline(QString(argv[1]));

正在抛出链接器错误,因为QString是由r引用传递的,在QImage尝试访问时被销毁。所以可能的修复方法是分别进行QString赋值,然后将其传递给QImage,这样就可以了:

QImage baseline(argv[1]);
QImage test_image(argv[2]);

1 个答案:

答案 0 :(得分:0)

首先,QImage baseline(QString(argv[1]))是一个最令人烦恼的解析。期。您正在使用不会向您发出警告的编译器。 (argv[1])周围的括号是多余的。该声明的规范形式为:

QImage baseline(QString [1]);

您也不应该使用argv,因为它不可移植。例如,在Windows上,argv是垃圾。

改为使用QCoreApplication::arguments()

int main(int argc, char ** argv) {
  QGuiApplication app{argc, argv};
  auto const args = app.arguments();
  if (args.count() < 3)
    return 1;
  QImage baseline(args[1]);
  QImage test_image(args[2]);  
  //...
}

如果你从一开始就使用它,你甚至不会遇到你遇到的问题。因此,您可以看到它们的好处是双重的:它可以保护您免受最棘手的解析,它在Windows上正常工作:)

当然,如果您有基于小部件的Ui,也可以使用QApplication。但对于QImage,您只需要QGuiApplication

常见Qt方法/构造函数的链接器错误(例如__declspec(dllimport) public: __thiscall QString::~QString(void)表示您未将项目与Qt链接。

如果您已经在使用qmake,那么只有在您未将#include <QtGui/QtGui>模块添加到项目中时才需要gui。正确的形式是#include <QtGui>。如果编译器抱怨它无法找到该文件,则您无法将项目设置为正确使用Qt。一旦你这样做,文件应该编译和链接 - 再次,假设你使用qmake或cmake和Qt宏。