qt - 图像
创始人
2025-05-28 05:24:09
0

qt - 图像

  • qt-图像操作
    • QPixmap
      • QLabel/QPixmap
      • QPushButton/QToolButton/QPixmap
      • QPixmap/QImage
      • QPixmap/imageReader
      • QPixmap/QByteArray
      • QPixmap/QDatastream/QFile
    • QImage
      • QImage/QPainter
      • QImage/QLabel
      • QImage/QPixmap
      • QImage/imageReader
      • QImage/QByteArray
      • QImage/QDatastream/QFile
    • QPicture
    • QBitmap
    • QImageReader/QImageWriter
  • QPainter绘图
    • 事件处理
    • 事件处理进阶
    • 绘制设置
    • 坐标系变换
    • 容器路径

qt-图像操作

https://blog.csdn.net/iriczhao/article/details/123265538
https://blog.csdn.net/weixin_44116061/article/details/106412187!!!
https://blog.csdn.net/qq_45662588/article/details/120366824

  • QPixmap
  • QImage
  • QBitmap
  • QPicture

QPixmap

图片类,用于显示图片
对于图片的显示做了优化处理
在平台有关,不同平台在内部的存储形式有区别
只能在主线程中使用

QPixmap对象可以通过值传递
QPixmap中的像素是由操作系统管理的
Qpixmap 中的像素只能通过Qpainter或转换成QImage才能访问

读取/写入

load()/loadFromdata() // 从本地文件或资源文件中读取
save() // 保存qpixmap对象

构建/保存

// 相当于一个画布,不依赖与Widget
QPixmap pix(400,300); // 像素是400,300
pix.fill(Qt::white);
QPainter painter(&pix);
painter.setPen(Qt::red);
painter.drawEllipse(QPoint(100,100),50,50);
pix.save("./mypix.jpg"); // 保存到本地磁盘
void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this);QPixmap pix;pix.load("mypix.jpg");painter.drawPixmap(0,0,50,50,pix); //在(0,0)点起始的宽高均为50的矩形中显示图片painter.translate(50,50); //将起始点改为(50,50)painter.drawPixmap(0,0,50,50,pix); //在(50,50)起始的宽高为50的矩形中显示图片
}

QLabel/QPixmap

QPixmap pix("/path");
QLabel label;
label.setPixmap(pix);
label.show();

QPushButton/QToolButton/QPixmap

可以基于QPixmap将图像显示到QPushButton/QToolButton

QPixmap/QImage

通常,QImage 类用于加载图像文件,并操作图像数据。然后将 QImage 对象转成 QPixmap 对象在屏幕上显示
如果不需要对像素进行操作,可以直接将图像加载到QPixmap中

QImage --> QPixmap

QPixmap::fromImage()

QPixmap --> QImage

QPixmap::toImage()

QPixmap/imageReader

fromImagereader

从直接从 imageReader 读取的图像创建 QPixmap

QPixmap/QByteArray

loadFromData
uchar* 或 QByteArray --> QPixmap
从直接从 imageReader 读取的图像创建 QPixmap

QPixmap/QDatastream/QFile

写入

将给定的像素图作为 PNG 图像写入给定的流。
注意,将流写入文件不会产生有效的图像文件

QFile file("file.dat");
QDataStream stream(&file);
file.open(QIODevice::WriteOnly);QPixmap pixmap("D://eee.jpg");
stream << pixmap;
file.close();

读取

从给定的流中读取图像到给定的像素图

QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream stream(&file);
QPixmap pixmap;
stream >> pixmap;
file.close();QLabel label;
label.setPixmap(pixmap);
label.show();

QImage

图片类,不依赖于平台,任何平台在内部的存储形式都是一样的
可以用于多线程中
多用于图片的传输可以做像素级的修改
I/O优化

读取/写入

load()/loadFromdata() // 从本地文件或资源文件中读取
save() // 保存qpixmap对象

加载/像素级修改

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);QImage img;img.load(":/images/images/bus.jpg");for (int i=50;i<100;i++){for (int j=50;j<100;j++){img.setPixel(i,j,qRgb(255,0,0));}}painter.drawImage(0,0,img);
}

QImage/QPainter

构建/保存

QImage img(400,300,QImage::Format_RGB32);
img.fill(Qt::white);
QPainter painter(&img);
painter.setPen(Qt::red);
painter.drawEllipse(QPoint(100,100),50,50);
img.save("./myimg.jpg"); // 保存到本地磁盘

加载/像素级修改

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);QImage img;img.load(":/images/images/bus.jpg");for (int i=50;i<100;i++){for (int j=50;j<100;j++){img.setPixel(i,j,qRgb(255,0,0));}}painter.drawImage(0,0,img);
}

QImage/QLabel

最好的方式是转换为QPixmap显示到QLabel

QImage/QPixmap

见QPixmap/QImage

QImage/imageReader

QImage/QByteArray

QImage/QDatastream/QFile

QPicture

可以理解为一个绘图的工具,保存有绘图的记录(类比QPainterPath)和重绘制的指令
存储的形式是二进制形式
与QPainter联合使用,用于记录和回播Qpainter

Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);QPicture pic;// version1
//    QPainter painter(&pic);
//    painter.setPen(Qt::red);
//    painter.drawEllipse(QPoint(100,100),50,50);
//    painter.end();// version2QPainter painter;painter.begin(&pic);painter.setPen(Qt::red);painter.drawEllipse(QPoint(100,100),50,50);painter.end();//    pic.save("./mypic.dat"); //二进制的形式}

加载

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);QPicture pic;pic.load("./mypic.dat");painter.drawPicture(0,0,pic);
}

QBitmap

只能是黑白图像 不能是彩色图像
继承自QPixmap 深度为1

QBitmap bm(400,300);
QPainter painter(&bm);
painter.setPen(Qt::red);
painter.drawEllipse(QPoint(100,100),50,50);
bm.save("./bm.jpg");

QImageReader/QImageWriter

QPainter绘图

QPaintEvent绘图事件 – > paintEvent绘图事件处理函数
当发生QPaintEvent绘图事件时,就自动调用paintEvent绘图事件处理函数

对于QPainterEvent绘图事件处理函数,当程序运行后,窗体自动调用QPainterEvent绘图事件处理函数

事件处理

void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this); // 创建一个QPainter类对象 调用构造函数 this指针指向的是当前Widget这个窗体painter.setPen(Qt::blue);painter.setFont(QFont("Arial",30));painter.drawText(rect(),Qt::AlignCenter,"Qt"); // rect表示在一个矩形的区域里绘制文字// 绘制文字QFont font("楷体",20,QFont::Bold,true); // 字体、字号、加速、斜体font.setUnderline(true); // 设置下划线painter.setFont(font);painter.setPen(Qt::blue);painter.drawText(50,50,"hello world"); // 50,50表示左上角坐标// 指定使用绘图工具QPen pen(QColor(255,0,0)); // 创建一个画笔pen.setWidth(3); // 设置粗细pen.setStyle(Qt::DashDotDotLine);painter.setPen(pen); // 使用绘笔// 画线painter.drawLine(QPoint(0,0),QPoint(100,100)); // 创建QPoint的匿名对象// 画圆painter.drawEllipse(QPoint(100,100),20,20);// 椭圆painter.drawEllipse(QPoint(100,100),50,30);// 矩形painter.drawRect(100,100,30,50); // (100,100)是左上角的坐标// 正方形painter.drawRect(100,100,80,80);// QPen 画笔// QBrush 画刷QBrush brush(Qt::green,Qt::Dense1Pattern);painter.setBrush(brush);
//    painter.setPen(pen); // 加不加setPen都行好像painter.drawRect(200,200,80,80);
}

事件处理进阶

#include "widget.h"
#include "ui_widget.h"
#include 
#include 
#include 
#include 
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);angle=0;// 创建定时器QTimer *timer=new QTimer(this);timer->start(1000);// QWidget::update 会自动调用paintEvent函数!!!void (QWidget:: *widget_update)()=&QWidget::update;connect(timer,&QTimer::timeout,this,widget_update); // 因为存储在函数重载
//    connect(timer,&QTimer::timeout,this,&QWidget::repaint);
}void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);// 更新angleangle+=10;if (angle==360) angle=0;// 抗锯齿painter.setRenderHint(QPainter::Antialiasing);// 将坐标系平移到当前窗体的中心,其始终是跟随状态//    this->width(),this->height()painter.translate(this->width()/2,this->height()/2);painter.drawEllipse(QPoint(0,0),120,120);painter.rotate(angle);painter.drawLine(QPoint(0,0),QPoint(100,0));}

绘制设置

锥形渐变

void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this); // 创建一个QPainter类对象 调用构造函数 this指针指向的是当前Widget这个窗体// 锥形渐变// 默认逆时针旋转,0表示实际的三点钟方向QConicalGradient conicalGradient(QPointF(200,100),0); // 创建一个对象 0表示angleconicalGradient.setColorAt(0.2,Qt::cyan); // 设置渐变色 0-1 0到360*0.2=72度逐渐变为Qt::cyanconicalGradient.setColorAt(0.4,Qt::black); // 设置渐变色 0-1 从72度到72+72度逐渐变为黑色conicalGradient.setColorAt(0.7,Qt::red); // 设置渐变色 0-1 黑色渐变位红色conicalGradient.setColorAt(0.7,Qt::yellow); // 设置渐变色 0-1painter.setBrush(conicalGradient); // 利用锥形渐变作为画刷painter.drawEllipse(QPointF(200,100),50,50);
}

抗锯齿

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);// version 1
//    QPen pen(QColor(255,0,0));
//    painter.setPen(pen);// version 2 创建匿名画笔painter.setPen(QPen(Qt::red,15));painter.drawEllipse(QPoint(200,200),100,100);// 抗锯齿painter.setRenderHints(QPainter::Antialiasing);painter.translate(200,0); // 向右平移,相当于坐标系平移painter.drawEllipse(QPoint(200,200),100,100);
} 

坐标系变换

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this); /* 坐标系旋转平移 */painter.setPen(QPen(Qt::red,10));// 直线painter.drawLine(QPoint(10,10),QPoint(100,100));painter.save(); // 保存当前坐标系(此时是初始状态)painter.translate(200,0); // 坐标系平移200painter.rotate(90); // 顺时针旋转90/*A --> A'\    /\  /\/B/B'*/painter.setPen(QPen(Qt::blue,10));painter.drawLine(QPoint(10,10),QPoint(100,100));/* 恢复坐标系 */painter.restore();painter.setPen(QPen(Qt::black,3));painter.drawLine(QPoint(11,11),QPoint(200,200));/* 坐标系旋转缩放 */painter.setPen(QPen(Qt::red,3));painter.setBrush(Qt::yellow); // 设置画刷用于填充painter.drawRect(50,50,50,50); // 正方形painter.save();painter.scale(1.5,2);painter.setBrush(Qt::green); // 设置画刷用于填充painter.drawRect(50,50,50,50); // 正方形
}

容器路径

QPainterPath 表示一个容器,可以放置之前绘制的各种各样的图形
目标就是要重复绘制

void Widget::paintEvent(QPaintEvent*)
{QPainter painter(this);// 准备一个容器,设置容器内的内容QPainterPath painterPath;painterPath.moveTo(50,250); // 移动起始位置painterPath.lineTo(50,200);painterPath.lineTo(100,100);painterPath.addEllipse(QPoint(100,100),30,30);// 指定painter进行绘制painter.setPen(Qt::red);painter.drawPath(painterPath);// 容器移动坐标系painterPath.translate(200,0);painter.setPen(Qt::blue);painter.drawPath(painterPath);
}

相关内容

热门资讯

不良率上升倒逼防线前移 银行收... 银行正在给个人信贷风控“上强度”。上海证券报记者近期自业内多方了解到,不少银行零售信贷业务从审批权限...
自媒体新手如何快速涨粉?这5个... 自媒体新手如何快速涨粉?这5个技巧让你少走弯路! 嗨,我是小融。 最近很多刚入门自媒体的朋友问我,怎...
乌兰察布市财政局关于黄金领域非... 乌兰察布市财政局关于黄金领域 非法金融活动风险提示 近期,黄金价格波动频繁,市场热度持续攀升,各类假...
一只鸡蛋架“直发”俄罗斯 无锡... (来源:无锡新传媒) 转自:无锡新传媒 一只3D打印塑料鸡蛋架,成为无锡国际邮件互换局正式开通运营后...
武汉楼市开启红五月 新房成交量... 原标题:武汉楼市开启红五月 数据爆表,新房成交量较去年同期翻番 武汉城建未来中心项目营销中心现场来...
一家精神病院竟现身A股公司前十... 5月8日,有投资者发现,盛通股份前十大股东名单中,竟出现了一家精神病院的身影。这家精神病院全称为“上...
真的老了!哈登心魔难除 骑士还... 哈登又拉胯了。 刚刚过去的两场东部半决赛,骑士都输的相当狼狈,而哈登的发挥更是灾难级的。 半决赛G1...
精神病院通报成上市公司前十大股... 近日,上市公司盛通股份发布一季报,披露了前十大股东名单。其中,一家名为“上饶市广丰区十五岭山精神病医...
天溯计量发布年报 上市首年检测... 转自:中国经营网 文 近日,计量检测机构天溯计量(301449.SZ)发布了2025年年度报告。年...
原创 全... 美伊真要停火了? 一页纸协议让全球油价闪崩! 就在今天,全球市场被一条消息炸开了锅。美国白宫觉得,他...
百信银行业绩:26Q1净利润大... 4月底,中信百信银行股份有限公司(下称“百信银行”)2025年财报及2026年一季度报接连披露—— ...
美光科技股价单周飙升38% 市... 【CNMO科技消息】受全球内存芯片短缺影响,美光科技股价本周大幅上涨。截至周五收盘,美光股价报746...
江西一精神病院炒股,炒成上市公... 近日,上市公司盛通股份(002599.SZ)发布一季报,披露了前十大股东名单,其中一家名为“上饶市广...
专访中国太保副总裁俞斌:从“+... 拥抱AI(人工智能),不再是保险行业的“选择题”,而是关乎企业生存与发展的“必答题”,更是企业决胜未...
多平台优化算法:美团取消超时扣... 图片来源:界面图库 5月8日,网信中国发布消息称,生活服务类平台算法治理已取得初步成效,美团、淘宝、...
原创 2... 2025年,国内系统重要性银行名单正式公布。这是我国金融体系的核心支柱,一共21家银行入选,它们是维...
东海县供销总社:“供销+龙头企... 近日,东海县供销合作总社鼎味泰直营店正式开业。作为东海县供销系统打造的新型社企便民服务网点,该门店的...
原创 阿... 深夜,一家零食店铺的客服后台弹出一条消息:“我上次买的芒果干,这次想换个不那么酸的口味,再帮我推荐几...
和平湾全新项目前瞻 负公摊、唯... 在沈阳,如果想在主城核心区域找一块容积率低于1.5的住宅用地,难度有多大? 过去三年,沈阳主城核心区...
精神病院与国际投行高盛同在 盛... 近日,盛通股份(002599.SZ)发布一季报,其前十大股东名单中,第九位为“上饶市广丰区十五岭山精...