QImage 图片分割、保存

article/2025/10/19 5:36:30

QImage 图片分割、保存

简介

之前一直只用Qt做图片显示,这次突发奇想想用Qt做做图像相关的,就尝试了一下图片切割,保存。

QImage介绍

QImage类为Qt提供的一个支持图像算法处理的类库,可以精确到像素及单位。在我理解不是提供了什么算法,而是为图像计算提供了基础。

构造函数

QImage()
QImage(const QSize &size, QImage::Format format)
QImage(int width, int height, QImage::Format format)
QImage(uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
QImage(const uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
QImage(uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
QImage(const uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
QImage(const char *const [] xpm)
QImage(const QString &fileName, const char *format = nullptr)
QImage(const QImage &image)
QImage(QImage &&other)

提供了以上构造方法,支持 uchar* ,const uchar*,filename 等元素的构造。

Format

FormatDescriptionQt’s support
BMPWindows BitmapRead/write
GIFGraphic Interchange Format (optional)Read
JPGJoint Photographic Experts GroupRead/write
JPEGJoint Photographic Experts GroupRead/write
PNGPortable Network GraphicsRead/write
PBMPortable BitmapRead
PGMPortable GraymapRead
PPMPortable PixmapRead/write
XBMX11 BitmapRead/write
XPMX11 PixmapRead/write

QImage 支持的图片格式如上表所示,部分支持读写特性。

相关方法:

QImage::Format format() const
QImage convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags = Qt::AutoColor) const &
QImage convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags = Qt::AutoColor) &&
QImage convertToFormat(QImage::Format format, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags = Qt::AutoColor) const

图像操作:像素、RGB、位深度、color、size

图像载入:

bool load(const QString &fileName, const char *format = nullptr)
bool load(QIODevice *device, const char *format)
bool loadFromData(const uchar *data, int len, const char *format = nullptr)
bool loadFromData(const QByteArray &data, const char *format = nullptr)

图像数据:

uchar *bits()
const uchar *bits() const
int bytesPerLine() const
const uchar *constBits() const
const uchar *constScanLine(int i) const

RGB:

QRgb color(int i) const
QVector<QRgb> colorTable() const
QRgb pixel(const QPoint &position) const
QRgb pixel(int x, int y) const

思路介绍

图像切割思路如下:

1.载入图片
2.切割图片
->2.1 设置切割属性:将图片切割为 n*m 个图片
->2.2 计算每个图片的rect,保存为rect列表
->2.3 利用copy(Rect)函数将指定区域图片copy出来,存储到切割列表中
3.显示图片
-> 按照rect列表显示切割后的图片
4.保存图片
-> 将切割后的图片存储到指定位置

程序部分

类图

主要由三个类组成:Image类,负责图像操作部分。MainWindow,主线调度类,负责功能性调度,或者说逻辑模块,业务部分。splite类。图片剪切设置框

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Image类

image.cpp
image.h
image.ui
class image : public QWidget
{Q_OBJECTpublic:explicit image(QWidget *parent = nullptr);~image();//图片载入void imageLoad(const QString path);void imageLoad(const QString path, int &_width, int &_height);uchar* imageData();//图像切割void iamgeItems(int x, int y, QList<QImage> &imageList);void iamgeItems(int x, int y, QList<uchar*> &list);//uchar* 方便像素级的图像算法或者其他图像操作void iamgeItems(int x, int y, QVector<uchar*> & vector);//图像保存void imageSave();void imageSave(int index);void imageSave(int start,int end);//图像显示void imageShow();void imageShow(QList<QImage> &listImage);void imageShow(QList<uchar*> &listItems);void imageShow(QVector<uchar*> &VectorItems);static image* instance();
private:Ui::image *ui;QImage r_image;uchar * r_image_data;QList<QRect> _imageRects;QList<QImage> _imageList;QList<uchar*> _listItems;QVector<uchar*> _vectorItems;
};

图像载入

//利用load方法载入图像
void image::imageLoad(const QString path)
{r_image.load(path);
}void image::imageLoad(const QString path, int &_width, int &_height)
{r_image.load(path);_width = r_image.width();_height = r_image.height();
}

图像切割

void image::iamgeItems(int x, int y, QList<QImage> &imageList)
{int r_width = r_image.width();int r_height =  r_image.height();int cellWidth = r_width / x;int cellHeight = r_height / y;qDebug() << r_width << " " <<  r_height << " " << cellWidth << " " << cellHeight;for(int i = 0 ;i < x; i++ ){for (int j = 0; j < y; j++) {QRect rect(i * cellWidth,j * cellHeight, cellWidth,cellHeight);qDebug() << rect.x() << " " <<  rect.y() << " " << rect.width() << " " << rect.height();_imageRects.push_back(rect);imageList.push_back(r_image.copy(rect));}}_imageList = imageList;
}

图像保存

void image::imageSave()
{int i = 0;for(auto it : _imageList){QString imageName = QString("image/%1.jpg").arg(i);it.save(imageName);i++;}qDebug() << "iamge save ok";
}void image::imageSave(int index)
{_imageList.at(index).save(QString("image/%1.jpg").arg(index));
}

图像显示

void image::imageShow()
{for(int i = 0 ;i < _imageList.size() ; i++){QLabel * label = new QLabel(this);label->setGeometry(_imageRects.at(i));QPixmap pixmap(QPixmap::fromImage(_imageList.at(i)));label->setPixmap(pixmap);label->show();}
}

MainWindow

负责全部的业务逻辑部分,也就是通俗所说的调度。

mainwindow.cpp
mainwindow.h
mainwindow.ui
class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();void menuInit();
private:Ui::MainWindow *ui;void sltImportImage();void sltSpliteImage();void sltSaveImage();void sltcalcImage();
};

菜单初始化

void MainWindow::menuInit()
{QAction* importImage = ui->menuBar->addAction(QString("导入图片"));QAction* spliteImage = ui->menuBar->addAction(QString("切割图片"));QAction* saveImage = ui->menuBar->addAction(QString("保存图片"));QAction* calcImage = ui->menuBar->addAction(QString("算法"));connect(importImage,&QAction::triggered,this,&MainWindow::sltImportImage);connect(spliteImage,&QAction::triggered,this,&MainWindow::sltSpliteImage);connect(saveImage,&QAction::triggered,this,&MainWindow::sltSaveImage);connect(calcImage,&QAction::triggered,this,&MainWindow::sltcalcImage);
}

导入图片

void MainWindow::sltImportImage()
{QString imagePath = QFileDialog::getOpenFileName(this,"导入图片","./","*png *jpg");int imageWidth = 0,imageHeight = 0;ui->iamge->imageLoad(imagePath,imageWidth,imageHeight);ui->iamge->imageData();this->resize(imageWidth,imageHeight);
}

图片切割

void MainWindow::sltSpliteImage()
{splite *_splite = new splite();_splite->show();connect(_splite,&splite::sign_spliteinfo,[=](int x,int y){QList<QImage> imageItems;ui->iamge->iamgeItems(x,y,imageItems);ui->iamge->imageShow();});
}

图像保存

void MainWindow::sltSaveImage()
{ui->iamge->imageSave();
}

图像算法选择

void MainWindow::sltcalcImage()
{//设计中选择图像算法,注册对应图像算法,选择实现对应的图像算法//算法模块中,特意提供了将图像数据列表,方便算法操作。//近期会找一两个比较简单的图像算法来实现
}

其他函数说明

主函数

int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

splite构造函数

splite::splite(QWidget *parent) :QWidget(parent),ui(new Ui::splite)
{ui->setupUi(this);connect(ui->pushButton_right,&QPushButton::clicked,[=](){emit sign_spliteinfo(ui->lineEdit_x->text().toInt(),ui->lineEdit_y->text().toInt());this->close();});connect(ui->pushButton_cancel,&QPushButton::clicked,[=](){this->close();});
}

运行效果

主程序界面

在这里插入图片描述

图像载入

在这里插入图片描述

图像切割

在这里插入图片描述

图像保存
在这里插入图片描述
在这里插入图片描述

源码

Gitee


http://chatgpt.dhexx.cn/article/7uvPKlZS.shtml

相关文章

QImage类

QImage类提供了一个硬件无关的图像表示方法&#xff0c;该图像可以逐像素被访问和用于画图设备。 Qt提供了QImage、QPixmap、QBitmap和QPicture四种图像操作类。QImage类主要用于I/O和直接逐像素访问、操作&#xff1b;QPixmap主要用于在屏幕中显示图像&#xff1b;QBitmap是一…

Qt使用QImage保存成JPG(PNG)图像到本地

一、QImage类简介 QImage提供了一个与硬件无关的图像表示方法&#xff0c;允许直接访问像素数据&#xff0c;可用作绘图设备。QImage类支持QImage::Format、enum描述的多种图像格式。包括8-bit, 32-bit 和alpha混合图像QImage 提供很多可以用于获取图像信息和进行图像变换的函…

QImage

一、描述 QImage 类提供了一种独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并且可以用作绘图设备。 QImage 是为 I/O 和直接像素访问和操作而设计和优化的&#xff0c; 因为 QImage 是 QPaintDevice 的子类&#xff0c;所以 QPainter 可用于直接在图像…

图像处理 QImage

在Qt中有四种处理图像的方法&#xff1a; QImage &#xff1a;使用I/O &#xff0c;可以对像素进行处理QPixmap&#xff1a;主要用在屏幕的显示QBitmap&#xff1a; QPixmap的子类&#xff0c;处理颜色深度&#xff0c;只能显示黑白两种颜色&#xff0c;用于遮罩QPicture&…

QImage的用法

QImage提供了几种加载图像文件的方法&#xff1a; &#xff08;1&#xff09;构造QImage对象 Image myImage1 QImage(filename); 根据文件名打开图像 支持的图片格式是&#xff1a; &#xff08;2&#xff09;QImage(uchar *data, int width, int height, Format format …) 用…

QImage使用说明

详细描述 QImage类提供独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并可用作绘制设备。 Qt提供了四个用于处理图像数据的类&#xff1a;QImage、QPixmap、QBitmap和QPicture。QImage针对I/O、直接像素访问和操作进行了设计和优化&#xff0c;而QPixmap…

QImage类详解(QImage类型转换、QImage类函数及QImage像素操作)

QImage类&#xff08;QImage类型转换、QImage类函数及QImage像素操作&#xff09; 打开Qt帮助文档&#xff0c;会看到有关于QImage的描述如下&#xff1a;The QImage class provides a hardware-independent image representation that allows direct access to the pixel dat…

J1939 协议

J1939 协议简介 J1939协议是基于CAN 2.0B所发展的出来的&#xff0c;基于CAN 的物理层。主要用于commercial vehicle的通信。J1939的主要目的是制定统一的上层application诊断的信息。 J1939的最大特点是定义了PGN&#xff08;Parameter Group Number). 大多数的PGN是8个字节…

SAE J1939学习笔记(三)

J1939故障代码种类 J1939 由几个不同的诊断信息&#xff1a; –诊断信息 1 - DM1 – 现行故障代码 –诊断信息 2 - DM2 – 非现行故障代码 –诊断信息 3 - DM3 – 清除非现行故障代码 通常地&#xff0c;用户会用 DM1 信息来读取现行故障码。 DM1 信息是 PGN 65226 or FECA h…

新功能发布—TSMaster如何实现J1939多帧报文收发

前言 众所周知&#xff0c;J1939协议是由美国汽车工程师协会&#xff08;SAE&#xff09;定义的一组标准。J1939标准用于卡车、公共汽车和移动液压等重型车辆。如今大多数车辆都通过CAN进行ECU通信。但是CAN总线仅仅是提供了通信的基础&#xff08;就像是电话&#xff09;&…

CAN协议 J1939

转自&#xff1a;http://blog.sina.com.cn/s/blog_bf97bd7e0102wl2y.html 这几天在公司看了SAE推行的 J1939标准&#xff08;SAE&#xff1a;美国汽车工程协会&#xff09;&#xff0c;这里整理下学习要点&#xff0c;主要包含以下几个协议&#xff1a; 物理层 SAE J1939-11…

J1939协议与CAN2.0对应关系图表

SAE J1939 消息帧格式定义与CAN 2.0B帧格式对应关系 J1939应用层协议详细描述了用于J1939网络的每个参数&#xff0c;包括其数据长度、数据类型、分辨率、范围及参考标签&#xff0c;并为每个参数分配了一个编号&#xff08;SPN&#xff09;。由于J1939协议是以协议数据单元&am…

Python实现CAN总线J1939报文接收、发送

前言 J1939协议是由美国汽车工程师协会&#xff08;SAE&#xff09; (SAE协会简介)定义的一组标准。J1939标准用于卡车、公共汽车和移动液压等重型车辆。在许多方面&#xff0c;J1939标准类似于旧版J1708和J1587标准&#xff0c;但J1939标准协议建立在CAN&#xff08;控制器区域…

J1939标准概述【小白入门】

文章目录 J1939标准概述&#xff1a;J1939/11物理层J1939/13板外诊断连接器J1939/21数据链路层J1939/31网络层J1939/71车辆应用层J1939/73应用层-诊断层J1939/81网络管理总结 J1939标准概述&#xff1a; J1939由下列子标准组成&#xff1a; J1939 – 串行控制和通信车辆网络…

J1939-21数据链路层多帧协议PDU解析

一、协议数据单元&#xff08;PDU&#xff09; P 是优先级&#xff0c;R 是保留位&#xff0c;DP 是数据页&#xff0c;PF 是PDU 格式&#xff0c;PS 是特定PDU&#xff0c;SA 是源地址 优先级&#xff08;P&#xff09;&#xff1a;这三位仅在总线传输中用来优化消息延迟&…

CAN总线的特点及J1939协议通信原理、内容和应用

众多国际知名汽车公司早在20世纪80年代就积极致力于汽车网络技术的研究及应用。迄今已有多种网络标准&#xff0c;如专门用于货车和客车上的SAE的J1939、德国大众的ABUS、博世的CAN、美国商用机器的AutoCAN、ISO的VAN、马自达的PALMNET等。 在我国的轿车中已基本具有电子控制和…

IPEmotion采集J1939协议信号

一 背景 由于商用车相对于乘用车更注重实用性&#xff0c;功能也较单一&#xff0c;且具有产量小的特点&#xff0c;因此在设计开发时需要进行约束&#xff0c;以更大程度实现软硬件的复用和成本的降低&#xff0c;在此需求下J1939协议便随之产生了。 J1939协议是由美国汽车工…

SAE J1939协议读取车辆故障码

基于SAE J1939协议的车辆&#xff0c;默认开启数据广播。当有故障码时&#xff0c;也会按照故障码的格式进行广播。 此处基于外设主动&#xff1a;读取故障码个数->读取故障码->故障码解析 这个步骤来讲&#xff0c;如果被动接收故障码广播&#xff0c;如下解析也适用。 …

车用总线技术 | J1939协议实用指南与J1939数据记录方案

“没错&#xff0c;这是一份SAE J1939协议的简单、实用指南。”—虹科 开篇&#xff1a;在这篇介绍中&#xff0c;我们介绍了J1939协议的基本知识&#xff0c;其中包括PGN和SPN。因为这是一篇偏向应用的简介&#xff0c;所以您还将会学习到如何通过DBC文件解码J1939数据、如何…

SAE J1939协议学习笔记

引用百度百科&#xff1a; SAE J1939&#xff08;以下简称J1939&#xff09;是美国汽车工程协会&#xff08;SAE&#xff09;的推荐标准&#xff0c;用于为中重型道路车辆上电子部件间的通讯提供标准的体系结构。它由“卡车与大型客车电气与电子委员会”&#xff08;Track &am…