欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt绘制和保存成图片(手写签名)

程序员文章站 2022-05-22 10:19:02
...

想要实现的是,手写签名的效果,最终把手写的结果保存,也可以加上水印什么的。
在控件的 MouseButtonPress 和 MouseMove 事件中,保存绘制的路径,然后再 Paint 重绘事件中绘制即可:

  • 特别需要注意的是,QImage QPixmap构造时,只是分配了空间,但是没有清空内存的,所以需要使用 fill() 填充图像,否则可能会得到混乱的图像.
    QImage img(ui->widgetPaint->size(),QImage::Format_ARGB32);
    img.fill(Qt::white);
  • QPainter::setRenderHint((QPainter::Antialiasing,true))设置抗锯齿.
    QPen构造的参数可以设置绘制的线形、线条末端形状、线条交汇处形状等.
    QPainter painter(device);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setPen(QPen(Qt::black,7,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
  • 简单的添加水印的代码:
    QImage img(ui->widgetPaint->size(),QImage::Format_ARGB32);
    img.fill(Qt::white);
    {//水印
        QImage bg("bg.png");
        QPainter painter(&img);
        int len = sqrt(img.width() * img.width() + img.height() * img.height());
        painter.rotate(-45);
        for(int i = -len / 2;i < len / 2;i += bg.width()){
            bool flag = true;
            for(int j = 0;j < len;j += bg.height()){
                painter.drawImage(flag ? i : i - bg.width() / 2,j,bg);
                flag = !flag;
            }
        }
    }
    Paint(&img);

加水印后保存的效果:
Qt绘制和保存成图片(手写签名)

大概的代码:
.h

#ifndef WIDGETSIGN_H
#define WIDGETSIGN_H
#include <QWidget>
#include <vector>
namespace Ui {
class WidgetSign;
}
class WidgetSign : public QWidget
{
    Q_OBJECT
public:
    explicit WidgetSign(QWidget *parent = 0);
    ~WidgetSign();
protected:
    bool eventFilter(QObject * obj, QEvent * event);
    void paintEvent(QPaintEvent *);
private slots:
    void on_btnClear_clicked();
    void on_btnSave_clicked();
private:
    void Paint(QPaintDevice * device);
private:
    Ui::WidgetSign * ui;
    QVector<QVector<QPoint> > vec_;
};
#edif // WIDGETSIGN_H

.cpp

#include "WidgetSign.h"
#include "ui_WidgetSign.h"
#include "PublicStruct.h"
#include <math.h>
#include <QMouseEvent>
#include <QPainter>
#include <QBitmap>
WidgetSign::WidgetSign(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WidgetSign)
{
    ui->setupUi(this);
    ui->widgetPaint->installEventFilter(this);
}
WidgetSign::~WidgetSign()
{
    delete ui;
}
bool WidgetSign::eventFilter(QObject * obj, QEvent * event)
{
    if(obj == ui->widgetPaint){
        if(event->type() == QEvent::MouseButtonPress){
            vec_.push_back(QVector<QPoint>());
            vec_[vec_.size() - 1].push_back(((QMouseEvent *)event)->pos());
            ui->widgetPaint->update();
        }else if(event->type() == QEvent::MouseMove){
            vec_[vec_.size() - 1].push_back(((QMouseEvent *)event)->pos());
            ui->widgetPaint->update();
        }else if(event->type() == QEvent::Paint){
            Paint(ui->widgetPaint);
        }
    }
    return QWidget::eventFilter(obj,event);
}
void WidgetSign::on_btnClear_clicked()
{
    vec_ = QVector<QVector<QPoint> >();
    ui->widgetPaint->update();
}
void WidgetSign::on_btnSave_clicked()
{
    if(vec_.size() <= 0){
        TOAST("请先签名");
        return;
    }
    QImage img(ui->widgetPaint->size(),QImage::Format_ARGB32);
    img.fill(Qt::white);
    /*{//水印
        QImage bg("bg.png");
        QPainter painter(&img);
        int len = sqrt(img.width() * img.width() + img.height() * img.height());
        painter.rotate(-45);
        for(int i = -len / 2;i < len / 2;i += bg.width()){
            bool flag = true;
            for(int j = 0;j < len;j += bg.height()){
                painter.drawImage(flag ? i : i - bg.width() / 2,j,bg);
                flag = !flag;
            }
        }
    }*/
    Paint(&img);
    QString imgPath = "sign.png";
    bool ret = img.save(imgPath);
    TOAST(ret ? "签名保存成功" : "签名保存失败");
}
void WidgetSign::Paint(QPaintDevice * device)
{
    QPainter painter(device);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setPen(QPen(Qt::black,7,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    for(int i = 0;i < vec_.size();++i){
        for(int j = 0;j < vec_[i].size() - 1;++j){
            painter.drawLine(vec_[i][j],vec_[i][j + 1]);
        }
    }
}
void WidgetSign::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}