Qt,C++多功能二维码实现,绘制与解析

昨天的电子印章还没写完,先欠着,作者是一天一个控件,所以文档跟不上,也没办法,而且后期如果商用那么关键代码可能不会在公开,有关技术交流可加入QQ群717743458探讨。

今天的主题是二维码,二维码,二维码,重要的事情说三遍。

老规矩,先上图

图一默认风格

图二随机的二维码颜色

图三 码眼使用随机颜色

图四所有颜色均随机

图示中的自定义操作仅仅是冰山一角,毕竟自定义范围广泛是作者一惯的开发风格。所以有关所有自定义功能定义请参考下面的代码

/// 二维码形状
  enum LQRCODESSHAPE_INDEX
  {
    LQRCSHAPE_SQUARE = 0,              //正方形
    LQRCSHAPE_ROUNDE = 1,              //正圆形
    LQRCSHAPE_HEARTS = 2,              //心形
    LQRCSHAPE_BUBBLE = 3               //气泡形状
  };

  /// 二维码风格数据结构体
  typedef struct LQRCODESCTRLS_STYLE_{
    QColor                      cBkgColorsValue = QColor(255,255,255);  //控件背景色
    QColor                      cOutBorderColor = QColor(251,60,40);    //外边框颜色
    QColor                      cInnBorderColor = QColor(242,42,21);    //内边框颜色
    QColor                      cTextColorValue = QColor(253,28,33);    //文本颜色

    QColor                      cCodesEyeValues = QColor(22,22,22);     //码眼颜色
    QColor                      cCodesEyeBorder = QColor(11,11,11);     //码眼边框颜色
    QColor                      cQrCodeDotValue = QColor(22,22,22);     //二维码矩阵点颜色

    QColor                      cQrCodeLogosBkg = QColor(255,255,255,240); //二维码Logo背景色
    QColor                      cQrCodeLogosFrg = QColor(0,0,0);           //二维码Logo前景色
    QColor                      cLogosBorderClr = QColor(115,127,217);     //二维码Logo文字颜色

    uint                        uQrLogosPadding = 4;                    //二维码Logo边距

    uint                        uBkgStylesIndex = 2;                    //背景风格,0无背景色,1全局背景,2仅二维码矩形区域背景
    uint                        uBorderStyleIds = 0;                    //边框风格,0无边框,1单边框,2双边框
    double                      dOuterBorderWid = 2.0;                  //外边框宽度
    double                      dInnerBorderWid = 0.75;                 //内边框宽度
    double                      dBkgRadiusValue = 0.01;                 //矩形圆角比例
    double                      dDotRadiusValue = 0.01;                 //二维码矩阵点圆角比例
    double                      dEyeBorderRadiu = 0.5;                  //二维码码眼边框圆角比例
    double                      dEyePointRadius = 0.5;                  //二维码码眼中心点圆角比例

    uint                        uCodeMaxLengths = 128;                  //二维码内容最大长度
    uint                        uLogoTextMaxLen = 8;                    //二维码Logo文本最大长度
    uint                        uTipsMaxLengths = 32;                   //二维码提醒文本最大长度
    uint                        uShowCenterLogo = 1;                    //是否显示Logo,0不显示,1显示logo图像,2显示logo文本,3同时显示Logo图像和文本
    bool                        bShowLogoFrames = true;                 //是否显示logo框架

    uint                        uCodesEyesShape = 0;                    //码眼形状,0表示矩形,1表示圆形。矩形支持圆角矩形
    uint                        uCodesDotsShape = 0;                    //二维码矩阵点形状,0表示矩形,1表示圆形。矩形支持圆角矩形

    QFont                       fLogoFontObject;                        //Logo字体对象
    QFont                       fTipsFontObject;                        //提醒信息字体对象
    uint                        uLogosFontSizes = 9;                    //Logo字体大小
    uint                        uTipsFontsSizes = 7;                    //标识提醒文字字体大小
    double                      dLogosScaleSize = 5.0;                  //Logo大小比例
    bool                        bHasRandomColor = false;                //是否使用随机颜色
    double                      dLooserArranged = 0;                    //松散因子基数,默认0,当矩阵点数减去因子差小于4时因子将不再参与计算
    double                      dCodesCharScale = 1.0;                  //自定义二维码字符比例
    bool                        bUseCustomsChar = false;                //是否使用自定义二维码字符矩阵
    bool                        bEyeRandomColor = false;                //是否使用自定义二维码码眼颜色

    double                      dBordersPadding = 6;                    //边框边距

    double                      dImgBorderWidth = 2.0;                  //Logo边框宽度
    double                      dImgBorderRadiu = 0.5;                  //Logo圆角比例

    LQRCODESSHAPE_INDEX         eQrCodeShapesId = LQRCSHAPE_SQUARE;     //二维码形状

    bool operator == (const LQRCODESCTRLS_STYLE_& rhs) // == 操作运算符重载
    {
      return (cBkgColorsValue == rhs.cBkgColorsValue)
          && (cOutBorderColor == rhs.cOutBorderColor)
          && (cInnBorderColor == rhs.cInnBorderColor)
          && (cTextColorValue == rhs.cTextColorValue)
          && (cCodesEyeValues == rhs.cCodesEyeValues)
          && (cCodesEyeBorder == rhs.cCodesEyeBorder)
          && (cQrCodeDotValue == rhs.cQrCodeDotValue)
          && (cQrCodeLogosBkg == rhs.cQrCodeLogosBkg)
          && (cQrCodeLogosFrg == rhs.cQrCodeLogosFrg)
          && (uQrLogosPadding == rhs.uQrLogosPadding)
          && (cLogosBorderClr == rhs.cLogosBorderClr)
          && (uBkgStylesIndex == rhs.uBkgStylesIndex)
          && (uBorderStyleIds == rhs.uBorderStyleIds)
          && (DoubleValCompare(dOuterBorderWid,rhs.dOuterBorderWid))
          && (DoubleValCompare(dInnerBorderWid,rhs.dInnerBorderWid))
          && (DoubleValCompare(dBkgRadiusValue,rhs.dBkgRadiusValue))
          && (DoubleValCompare(dDotRadiusValue,rhs.dDotRadiusValue))
          && (DoubleValCompare(dEyeBorderRadiu,rhs.dEyeBorderRadiu))
          && (DoubleValCompare(dEyePointRadius,rhs.dEyePointRadius))
          && (uShowCenterLogo == rhs.uShowCenterLogo)
          && (uCodeMaxLengths == rhs.uCodeMaxLengths)
          && (uLogoTextMaxLen == rhs.uLogoTextMaxLen)
          && (uTipsMaxLengths == rhs.uTipsMaxLengths)
          && (bShowLogoFrames == rhs.bShowLogoFrames)
          && (uCodesEyesShape == rhs.uCodesEyesShape)
          && (uCodesDotsShape == rhs.uCodesDotsShape)
          && (uLogosFontSizes == rhs.uLogosFontSizes)
          && (uTipsFontsSizes == rhs.uTipsFontsSizes)
          && (DoubleValCompare(dLogosScaleSize,rhs.dLogosScaleSize))
          && (bHasRandomColor == rhs.bHasRandomColor)
          && (eQrCodeShapesId == rhs.eQrCodeShapesId)
          && (DoubleValCompare(dLooserArranged,rhs.dLooserArranged))
          && (DoubleValCompare(dCodesCharScale,rhs.dCodesCharScale))
          && (DoubleValCompare(dImgBorderWidth,rhs.dImgBorderWidth))
          && (DoubleValCompare(dImgBorderRadiu,rhs.dImgBorderRadiu))
          && (bUseCustomsChar == rhs.bUseCustomsChar)
          && (bEyeRandomColor == rhs.bEyeRandomColor)
          && (dBordersPadding == rhs.dBordersPadding);
    }

    bool operator != (const LQRCODESCTRLS_STYLE_& rhs) // != 操作运算符重载
    {
      return !(*this == rhs);
    }
  }LQRCODESCTRLS_STYLE,*PLQRCODESCTRLS_STYLE;

看到上面的自定义风格结构体有没有被震撼到。如果没有当我没说

有关绘制代码和核心功能代码定义如下

/// 标准构造
    /// \brief Lncf_QtQrcodeCtrls
    /// \param parent
    /// \param bOutMode 是否为解析模式
    ///
    explicit Lncf_QtQrcodeCtrls(QWidget *parent = nullptr,bool bParse=false);

    ~Lncf_QtQrcodeCtrls();
  protected:
    /// 初始化印章控件
    /// \brief InitElectronicSeal
    ///
    virtual void InitElectronicSeal();
  protected:
    ///重写系统绘制事件
    virtual void paintEvent(QPaintEvent *event) override;

    /// 绘制二维码边框
    /// \brief DrawQrCodeBorders
    /// \param painter
    ///
    virtual void DrawQrCodeBorders(QPainter *painter);

    /// 绘制二维码图像
    /// \brief DrawQrCodesImages
    /// \param painter
    ///
    virtual void DrawQrCodesImages(QPainter *painter);

    /// 绘制码眼标识
    /// \brief DrawQrCodeEyeTags
    /// \param painter
    /// \param index
    /// \param rc
    ///
    virtual void DrawQrCodeEyeTags(QPainter *painter,int index,QRectF rc);

    /// 绘制二维码矩阵点
    /// \brief DrawQrMatrixPoint
    /// \param painter
    ///
    virtual void DrawQrMatrixPoint(QPainter *painter,QRectF rc);

    /// 绘制二维码Logo
    /// \brief DrawsQrCodesLogos
    /// \param painter
    ///
    virtual void DrawsQrCodesLogos(QPainter *painter);
  private:
    LQRCODESCTRLS_STYLE tCtrlsStyleData;    //控件风格数据结构体
    bool                bParseImageMode;    //是否为解析模式,默认为生成模式
    std::u16string      sQrCodeTxtValue;    //二维码数据
    std::u16string      sQrLogoTxtValue;    //二维码Logo文本
    std::u16string      sQrLogoImgsPath;    //二维码Logo图像路径
    char16_t            cCodeMatrixChar;    //二维码自定义矩阵点文字
  public:
    /// 生成二维码图像
    /// \brief BuildQrCodeImages
    /// \param sValue      :二维码内容
    /// \param sError      :错误信息
    /// \return
    ///
    bool BuildQrCodeImages(const std::u16string& sValue,std::u16string& sError);

    /// 生成二维码图像并输出QPixmap引用
    /// \brief BuildQrCodeImages
    /// \param sValue      :二维码内容
    /// \param pPixmap     :生成的图像
    /// \param sError      :错误信息
    /// \return
    ///
    bool BuildQrCodeImages(const std::u16string& sValue,const QPixmap& pPixmap,std::u16string& sError);

    /// 生成二维码图像并输出QImage引用
    /// \brief BuildQrCodesImage
    /// \param sValue      :二维码内容
    /// \param pImage      :生成的图像
    /// \param sError      :错误信息
    /// \return
    ///
    bool BuildQrCodesImage(const std::u16string& sValue,const QImage& pImage,std::u16string& sError);

    /// 解析文件二维码图像内容
    /// \brief ParseQrCodesImage
    /// \param sPath       :文件路径
    /// \param sError      :错误信息
    /// \return
    ///
    bool ParseQrCodesImage(const std::u16string& sPath,std::u16string& sError);

    /// 解析URL二维码图像内容
    /// \brief ParseQrCodesImage
    /// \param sUrl        :网络URL
    /// \param sError      :错误信息
    /// \return
    /// 注意:若返回false并且sError=“function not provided”表示在您使用的版本中此功能尚未支持
    ///
    bool ParseQrCodesImage(const QUrl& sUrl,std::u16string& sError);

    /// 解析QPixmap对象二维码图像内容
    /// \brief ParseQrCodesImage
    /// \param pImage      :QPixmap图像对象
    /// \param sError      :错误信息
    /// \return
    ///
    bool ParseQrCodesImage(const QPixmap& pImage,std::u16string& sError);

    /// 解析QImage对象二维码图像内容
    /// \brief ParseQrCodesImage
    /// \param pImage      :QImage图像对象
    /// \param sError      :错误信息
    /// \return
    ///
    bool ParseQrCodesImage(const QImage& pImage,std::u16string& sError);

    /// 复制二维码图像到剪贴板
    /// \brief CopyQrCodesImages
    /// \param sError      :错误信息
    /// \return
    ///
    bool CopyQrCodesImages(std::u16string& sError);

    /// 保存二维码图像到文件
    /// \brief SaveQrCodesImages
    /// \param sFile       :要保存的文件路径
    /// \param sError      :错误信息
    /// \param bOverlay    :是否覆盖重复的文件,默认false,如果遇到同名文件会返回false
    /// \return
    ///
    bool SaveQrCodesImages(const std::u16string &sFile,std::u16string& sError,const bool bOverlay = false);

每天干活十四个小时确实很累,所以部分实现代码仍然欠着,因为还没写完,写完了补上

最后老规矩

有关详细信息和技术交流,移步QQ群:717743458。

你可能感兴趣的:(qt,c++,开发语言)