Qt 制作验证码

Qt 制作验证码


cpp 复制代码
#include <QRandomGenerator>
#include <QPainterPath>
#include <QPainter>

// 生成随机数
int r(int a,int b=0){
    return b ? QRandomGenerator::global()->bounded(a, b)
             : QRandomGenerator::global()->bounded(a);
}

// 生成随机多边形路径
QPainterPath createRandomPolygon(int width, int height) {
    QPainterPath path;
    int points = r(1, 7);
    QPointF center(r(width),r(height));

    for (int i = 0; i < points; ++i) {
        qreal radius = 1.0*r(3, 20);
        qreal angle = 2 * M_PI * i / points;
        QPointF pt = center + QPointF(radius * cos(angle), radius * sin(angle));
        if (i == 0) path.moveTo(pt);
        else path.lineTo(pt);
    }
    path.closeSubpath();
    return path;
}

void MainWindow::genRandomPixmap()
{
    // 生成随机4位数
    QString numberStr = QString::number(r(1000, 10000));

    // 创建画布
    QPixmap pixmap(ui->lbCode->size());
    pixmap.fill(Qt::white);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);

    // 字体设置
    QFont baseFont("Arial", 23, QFont::Bold);
    painter.setFont(baseFont);

    // 动态计算字符间距(考虑旋转扩展)
    QFontMetrics fm(baseFont);
    int charSpacing = fm.horizontalAdvance('0') * 1.4; // 基础间距

    // 计算安全绘制区域
    auto w = pixmap.width();
    auto h = pixmap.height();
    // 绘制每个字符
    for (int i = 0; i < numberStr.size(); ++i) {
        painter.save();

        // 随机颜色(避免过浅)
        QColor textColor(r(10, 210), r(10, 210),r(10, 210) );
        painter.setPen(textColor);

        // 获取字符尺寸
        QRect charRect = fm.boundingRect(numberStr[i]);

        // 生成随机变换参数
        qreal angle = r(-30, 30);
        qreal centerX = i*charSpacing + (charRect.width() >> 1) + 11;
        qreal centerY = h >> 1;
        qreal scaleX = 1.0 + 0.01*r(-15, 15); // X缩放
        qreal scaleY = 1.0 + 0.01*r(-15, 15); // Y缩放
        qreal shearX = 0.1*r(-5, 5);  // X倾斜
        qreal shearY = 0.1*r(-1,1);   // Y倾斜

        // 设置变换(以字符中心为旋转点)
        QTransform transform;
        transform.translate(centerX, centerY);
        transform.rotate(angle);
        transform.scale(scaleX, scaleY);     // 缩放
        transform.shear(shearX, shearY);     // 倾斜
        transform.translate(-charRect.width()/2, charRect.height()>> 1); // 对齐基线
        painter.setTransform(transform);

        // 添加位置抖动(限制在安全区)
        QPointF offset(r(-2,2), r(-2,2) );
        painter.drawText(offset, QString(numberStr[i]));

        painter.restore();
    }
    // 增强效果
    // 添加干扰线(可选)
    for (int i = 0; i <5; ++i) {
        painter.setPen(QColor(r(240), r(240), r(240), r(150, 250)));
        painter.drawLine(
            r(w), r(h),
            r(w), r(h)
        );
    }
    // 添加随机多边形(可选)
    for (int i = 0; i <5; ++i) {
        QPainterPath path = createRandomPolygon(w, h);
        painter.setPen(QColor(r(240), r(240), r(240), r(150, 250)));
        painter.drawPath(path);
    }

    ui->lbCode->setPixmap(pixmap);
}
相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能13 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G13 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt