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);
加水印后保存的效果:
大概的代码:
.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);
}
上一篇: jSignature插件手写签名生成图片
推荐阅读