Qt 制作验证码
#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);
}