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

想要实现的是,手写签名的效果,最终把手写的结果保存,也可以加上水印什么的。
在控件的 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);


加水印后保存的效果:


大概的代码:
.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);
}


————————————————
版权声明:本文为CSDN博主「yangyang031213」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yangyang031213/article/details/102639958

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值