一、基于Qt的图像矩形区域改色

Qt环境下图像的打开和涂色

一、设计目标

能够在 Qt QtCreator 环境下打开常用图像格式文件,诸如 bmpjpgpng 图像等,然后将他们转化为 Qt 中的 QImage 类,并进行矩形范围内的涂色。

 

二、需要提前掌握的知识

1.Qt 图像类

Qt 中用于图像操作的类有 QImage QPixmap,其中 QImage 主要负责图像编辑和修改,而 QPixmap 则负责图像的显示。

2.Qt 如何修改图像

QImage 中有一个 setPixelColor() 方法可以对image 的像素点进行操作,但是当需要操作的图像区域面积较大时,该方法的效率较低。这时最有效率的方法就是直接操作 image 在内存中的数据,可以通过 bits() 方法来获取 image 数据的首地址。

3.Qt 如何显示图像

Qt 中图像的显示主要是通过使用 QLabel 类来实现的。步骤:先打开一个图像;将图像加载进 QImage 中;在用 QPixmap 对象获得图像;最后用 QLabel 使用 setPixmap() 方法显示。

 

三、程序需求

1.一个包含打开图像,涂色功能的菜单的主窗口;

2.一个可以获取需要修改的矩形范围、颜色,并返回给主窗口的编辑对话框;

 

四、实现大致过程

1.首先实现主窗口和编辑对话框的布局;

2.分别在两个窗口中加入需要的信号和槽;

3.完成窗口内部控件以及两窗口之间的通信;

 

五、详细步骤

(一)主窗口

1.头文件

MainWindow 的头文件中引用头文件(Qt中使用一个类,就要引用这个类的头文件):

#include <Qlabel>

#include <QPixmap>

#include <QImage>

#include <QMenuBar>

#include <QMenu>

#include <QAction>

#include <QFileDialog>

#include <QString>

#include <QPoint>

#include <QDebug>

 

 

2.布局

MainWindow 的定义中加入

private:

    QLabel *label;

    QImage *image; // 全局image

    QMenuBar *menubar;

    QMenu *fileMenu;

    QMenu *editMenu;

    QAction *openAction;

    QAction *rectAction;

 

然后在MainWindow的构造函数中加入

    label = new QLabel(this);

    menubar = this->menuBar();

 

    fileMenu = menubar->addMenu("file");

    editMenu = menubar->addMenu("edit");

 

    openAction = fileMenu->addAction("openfile");

    rectAction = editMenu->addAction("rect");

 

这样,主窗口的空间布局就完成了。效果如下:

 

 

3.信号

MianWindow的定义中加入 freshSignal 信号,该信号用于通知窗口需要更新label上的图片内容:

signals:

    void freshSignal();

 

4.槽函数

MainWIndow的定义中加入下列槽函数:

private slots:

    void openFileSlot(); // 打开文件

    void freshSlot();  // 刷新label上的图片

    void editDialogSlot(); // 打开编辑对话框

void rectChangeSlot(QPoint,QPoint,QColor); // 修改制定rect中的像素

 

它们的实现如下:

void MainWindow::openFileSlot()

{

    QString path = QFileDialog::getOpenFileName(

                        this,

                        "文件对话框",

                        "../",//上一级路径

                        "Image(*.bmp *.jpg *.png)"

                       );

    image = new QImage(path);

 

    emit freshSignal();

}

 

void MainWindow::freshSlot()

{

    label->setPixmap(QPixmap::fromImage(*image));

 

    label->resize(image->size());

}

 

void MainWindow::editDialogSlot()

{

    editDialog->show();

}

 

void MainWindow::rectChangeSlot(QPoint startPoint,QPoint endPoint,QColor color)

{

    // Qt 打开的 bmp、jpg 图像格式为 Format_RGB32,在内存中的顺序为 B G R 0

    //    打开的 png 图像的格式为 Format_ARGB32,在内存中的顺序为 B G R A

    unsigned char *scrdata = image->bits();

    int width = image->width();

    int height = image->height();

    int bytesPerLine = image->bytesPerLine();//图像每行字节对齐

    unsigned char *dstdata = new unsigned char[bytesPerLine*height];//存储处理后的数据

 

    int r = color.red();

    int g = color.green();

    int b = color.blue();

 

    for(int i=0;i<height;i++)

        for(int j=0;j<width;j++)

        {

            if((i>=startPoint.x())&&i<endPoint.x()&&

                    (j>=startPoint.y())&&j<endPoint.y())

            {

                dstdata[i*bytesPerLine+j*4]  = b;

                dstdata[i*bytesPerLine+j*4+1]= g;

                dstdata[i*bytesPerLine+j*4+2]= r;

            }

            else{

                dstdata[i*bytesPerLine+j*4]  = scrdata[0];

                dstdata[i*bytesPerLine+j*4+1]= scrdata[1];

                dstdata[i*bytesPerLine+j*4+2]= scrdata[2];

            }

            scrdata+=4;

        }

    image= new QImage(dstdata,width,height,bytesPerLine,QImage::Format_RGB32);

 

    emit freshSignal();

}

 

5.连接信号与槽

MainWindow的实现函数中进行连接:

connect(openAction,SIGNAL(triggered()),this,SLOT(openFileSlot()));

connect(this,SIGNAL(freshSignal()),this,SLOT(freshSlot()));

connect(rectAction,SIGNAL(triggered()),this,SLOT(editDialogSlot()));

 

这样,MainWindow 的实现就基本完成

(二)编辑对话框

1.创建编辑对话框类

编辑对话框类需要自己创建,步骤:右键项目文件夹->添加新文件->选择C++

->选择基类为QWidget->命名为EditDialog->完成。这样工程就会自动添加两个新的文件

 

,编辑对话框创建完成。

2.头文件

EditDialog 的头文件中加入头文件(Qt中使用一个类,就要引用这个类的头文件):

#include <QLabel>

#include <QGridLayout>

#include <QPushButton>

#include <QLineEdit>

#include <QPoint>

 

3.布局

EditDialog 的定义中加入

public:

    QGridLayout *layout;

    QLabel *startLabel;

    QLabel *endLabel;

    QLineEdit *x1Text;

    QLineEdit *y1Text;

    QLineEdit *x2Text;

    QLineEdit *y2Text;

    QLabel *rLabel;

    QLabel *gLabel;

    QLabel *bLabel;

    QLineEdit *rText;

    QLineEdit *gText;

    QLineEdit *bText;

    QPushButton *okButton;

 

然后在 EditDialog 的构造函数中加入

  

  layout = new QGridLayout(this);

    startLabel = new QLabel("start",this);

    endLabel = new QLabel("end",this);

    x1Text = new QLineEdit("0",this);

    y1Text = new QLineEdit("0",this);

    x2Text = new QLineEdit("100",this);

    y2Text = new QLineEdit("100",this);

    rLabel = new QLabel("R:",this);

    gLabel = new QLabel("G:",this);

    bLabel = new QLabel("B:",this);

    rText = new QLineEdit("0",this);

    gText = new QLineEdit("0",this);

    bText = new QLineEdit("0",this);

    okButton = new QPushButton("OK",this);

 

    layout->addWidget(startLabel,0,0,1,1); // 添加布局

    layout->addWidget(x1Text,0,1,1,1);

    layout->addWidget(y1Text,0,2,1,1);

    layout->addWidget(endLabel,1,0,1,1);

    layout->addWidget(x2Text,1,1,1,1);

    layout->addWidget(y2Text,1,2,1,1);

    layout->addWidget(rLabel,2,0,1,1);

    layout->addWidget(gLabel,3,0,1,1);

    layout->addWidget(bLabel,4,0,1,1);

    layout->addWidget(rText,2,1,1,1);

    layout->addWidget(gText,3,1,1,1);

    layout->addWidget(bText,4,1,1,1);

    layout->addWidget(okButton,2,2,1,1);

 

这样 EditDialog 的布局完成,效果如下

 

 

4.信号

EditDialog 的定义中加入如下信号,该信号用于向 MainWindow 返回需要涂色的矩形起点和终点,并告诉 MainWIndow 执行涂色操作。

signals:

    void resultSignal(QPoint,QPoint,QColor);

 

5.槽函数

EditDialog 的定义中加入如下函数

public slots:

    void okButtonSlot(); // 处理案件操作

 

槽函数的实现:

void EditDialog::okButtonSlot()

{

    int x1 = x1Text->text().toInt();

    int y1 = y1Text->text().toInt();

    int x2 = x2Text->text().toInt();

    int y2 = y2Text->text().toInt();

    int r = rText->text().toInt();

    int g = gText->text().toInt();

    int b = bText->text().toInt();

    QPoint startPoint = QPoint(x1,y1);

    QPoint endPoint = QPoint(x2,y2);

    QColor color = QColor(r,g,b);

 

    emit resultSignal(startPoint,endPoint,color);

 

    this->hide();

}

 

6.连接信号与槽

EditDialog 的构造函数中加入

connect(okButton,SIGNAL(clicked()),this,SLOT(okButtonSlot()));

(三)主窗口与编辑对话框的连接

1. MainWindow 的头文件中引用头文件

#include "editdialog.h"

2. MainWindow 的定义中加入

EditDialog *editDialog;

3. MainWindow 的构造函数中加入

editDialog = new EditDialog();

4. MainWIndow 的构造函数中加入

connect(editDialog,SIGNAL(resultSignal(QPoint,QPoint,QColor)),this,SLOT(rectChangeSlot(QPoint,QPoint,QColor)));

至此,整个程序就编写完成,效果图如下:

 

 

github代码链接:

https://github.com/851984709/Junjie-Hu/tree/master/code/qt/task/BmpEdit

 

如果上述教程或代码中有任何错误,欢迎批评和指证。

转载于:https://www.cnblogs.com/akakakkk/p/8534644.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中的QObject类并没有提供直接将对象转换为矩形区域的方法。但是,可以通过使用QWidget类和QRect类来实现将QObject对象转换为矩形区域的效果。 QWidget是Qt中用于创建用户界面的基类,它继承自QObject类,并提供了绘制和显示的功能。QRect是Qt中用于表示矩形区域的类,可以通过指定左上角坐标和矩形的宽度和高度来定义一个矩形。 要将QObject对象转换为矩形区域,可以按照以下步骤进行操作: 1. 将QObject对象强制转换为QWidget对象。可以使用qobject_cast<>()函数来实现。如果转换成功,返回指向QWidget对象的指针;否则返回空指针。 2. 使用QWidget对象的geometry()函数获取其在父组件中的几何属性,即左上角坐标和宽度高度。 3. 将获取的几何属性与QRect类的构造函数参数进行对应,创建一个QRect对象。可以使用QRect(int x, int y, int width, int height)的方式来创建一个QRect对象。 下面是一个示例代码: ```cpp QObject *object = new QObject(); QWidget *widget = qobject_cast<QWidget *>(object); if (widget) { QRect rect(widget->geometry().x(), widget->geometry().y(), widget->geometry().width(), widget->geometry().height()); // 使用矩形区域rect进行后续的操作 } else { // 无法将QObject对象转换为QWidget对象 } ``` 通过以上步骤,你可以将一个QObject对象转换为矩形区域的表示,并使用这个矩形区域进行后续的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值