Qt图像处理与绘制基础

Qt提供了四个类来处理图像数据:QImage, QPixmap, QBitmap和QPicture

       -QImage是为I/O和直接像素访问和操作而设计和优化的,

       -QPixmap是为屏幕上显示图像而设计和优化的

       -QBitmap只是一个继承QPixmap的便利类

       -QPicture类是一个绘制设备,用于记录和回放QPainter操作

QPicture的理解

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPicture picture;
    QPainter painter;
    painter.begin(&picture);           // paint in picture
    painter.drawEllipse(10,20, 80,70); // draw an ellipse
    painter.end();                     // painting done
    picture.save("drawing.pic");       // save picture
}

void Widget::paintEvent(QPaintEvent *)
{
    QPicture pic;
    pic.load("drawing.pic");
    QPainter p;
    p.begin(this);               // paint in current widget
    p.drawPicture(0, 0, pic);    // draw the pic at (0,0)
    p.end();
}

设备无关图像类 - QImage

       -独立于具体硬件的图像类 ,主要用于读写图像文件,针对IO访问而设计 ,能够直接在像素级对图像进行处理 

       -读取图像文件,直接进行像素级操作 ,内置简易图像处理相关算法 

       -加载图像的三种方式:带参构造函数,load函数,fromData函数

设备相关图像类 - QPixmap

       -依赖于具体硬件的图像类 ,主要是用于绘图,针对屏幕显示而设计 ,显示效果依赖于所在平台的绘制引擎(不可移植)

       -最大限度利用硬件(显卡)加速,增强图像显示效果。屏幕截图,窗口截图,组件截图,...

              ◆ grabWindow() 用于对屏幕图像进行抓取

              ◆ grabWidget() 用于对当前程序中的组件外观图像进行抓取

适用场合 

       -Qlmage适用于直接进行图像处理的场合 ,QPixmap适用于在界面上显示图像的场合 

       -QPixmap能够对Qlmage图像进行转换 ,QPainter能够直接在图像对象上进行绘图 

       -Qt图像类都继承自QPaintDevice QPainter能够直接在图像上绘制图形 

   

QImage像素操作

存储在QImage中的每个像素都用一个整数表示。整数的大小取决于格式

8位图像使用8位索引存储在一个颜色表中,即每个像素有一个字节。颜色表是一个QVector<QRgb>, QRgb 相当于一个unsigned int,包含格式为0xAARRGGBB

32位图像没有颜色表;相反,每个像素包含一个QRgb值,包含alpha通道、红、绿、蓝通道。通过这些通道能够确定一个像素的各种颜色。默认的alpha通道是ff,即不透明

    // 32bit
    QImage image(3, 3, QImage::Format_RGB32); // 图像使用32位RGB格式存储
    QRgb value;
    
    value = qRgb(189, 149, 39); // 0xffbd9527, ff代表不透明
    image.setPixel(1, 1, value);
    
    value = qRgb(122, 163, 39); // 0xff7aa327
    image.setPixel(0, 1, value);
    image.setPixel(1, 0, value);
    
    value = qRgb(237, 187, 51); // 0xffedba31
    image.setPixel(2, 1, value);
    
    // 8bit
    QImage image(3, 3, QImage::Format_Indexed8); // 图像使用8位索引存储到一个颜色映射中
    QRgb value;
    
    value = qRgb(122, 163, 39); // 0xff7aa327
    image.setColor(0, value);
    
    value = qRgb(237, 187, 51); // 0xffedba31
    image.setColor(1, value);
    
    value = qRgb(189, 149, 39); // 0xffbd9527
    image.setColor(2, value);
    
    image.setPixel(0, 1, 0);
    image.setPixel(1, 0, 0);
    image.setPixel(1, 1, 2);
    image.setPixel(2, 1, 1);

 

图像处理

Qt中的QColor类同时支持多种颜色表示方式

        - RGB: 以红,绿,蓝为基准的三色模型 

        - HSV: 以色调,饱和度,明度为基准的六角锥体模型 

        - CMYK: 以天蓝,品红,黄色,黑为基准的全彩印刷色彩模型 

颜色通常按照RGB(红、绿、蓝)来指定,但是也可以按照HSV和CMYK来指定

QColor构造函数根据RGB值创建颜色。可以使用toHsv()和toCmyk()函数 得到HSV或CMYK创建的QColor

       -想提高图片的亮度,可以增高红绿蓝通道的颜色,偏白效果

       -想提高图片的灰度,可以综合红绿蓝通道的颜色,偏白效果

       -想提高图片的暖色,可以增高红色和绿色,偏黄效果

       -想提高图片的冷色,可以增高蓝色

       -可以用RGB构建QColor,再转换为HSV创建的QColor,再提高各个参数

 

重置图像大小并灰度化 main.cpp

#include <QtCore/QCoreApplication>
#include <QImage>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QImage img;

    if( img.load("test.jpg") ) // 也可以直接QImage构造函数中传参加载
    {
        img = img.scaled(QSize(img.width() / 2, img.height() / 2));

        for(int i=0; i<img.width(); i++)
        {
            for(int j=0; j<img.height(); j++)
            {
                QRgb rgb = img.pixel(i, j); // 该函数开销很大; 如果考虑性能,建议使用scanLine()一次读取整行像素值
                int r = qRed(rgb);
                int g = qGreen(rgb);
                int b = qBlue(rgb);
                int gray = (r + g + b) / 3;

                img.setPixel(i, j, qRgb(gray, gray, gray));
            }
        }

        img.save("new.jpg");
    }
    
    return a.exec();
}

屏幕截图 Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QWidget>
#include <QPushButton>
#include <QPixmap>

class Widget : public QWidget
{
    Q_OBJECT

    QPushButton m_loadBtn;
    QPushButton m_grabBtn;
    QPixmap m_pmap; // 支持隐式共享

private slots:
    void onLoadBtnClicked();
    void onGrabBtnClicked();
protected:
    void paintEvent(QPaintEvent *);
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include <QPainter>
#include <QFileDialog>
#include <QImage>
#include <QMessageBox>
#include <QApplication>
#include <QDesktopWidget>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_loadBtn.setParent(this);
    m_loadBtn.move(10, 10);
    m_loadBtn.resize(70, 30);
    m_loadBtn.setText("Load");

    m_grabBtn.setParent(this);
    m_grabBtn.move(90, 10);
    m_grabBtn.resize(70, 30);
    m_grabBtn.setText("Grab");

    resize(500, 350);

    connect(&m_loadBtn, SIGNAL(clicked()), this, SLOT(onLoadBtnClicked()));
    connect(&m_grabBtn, SIGNAL(clicked()), this, SLOT(onGrabBtnClicked()));
}

void Widget::onLoadBtnClicked()
{
    QFileDialog fd(this);

    fd.setAcceptMode(QFileDialog::AcceptOpen);
    fd.setFileMode(QFileDialog::ExistingFile);

    if( fd.exec() == QFileDialog::Accepted )
    {
        QImage img;

        if( img.load(fd.selectedFiles()[0]) )
        {
            m_pmap = QPixmap::fromImage(img);

            update();
        }
        else
        {
            QMessageBox(QMessageBox::Critical, "Error", "Invalid image file!").exec();
        }
    }
}

void Widget::onGrabBtnClicked()
{
    m_pmap = QPixmap::grabWindow(QApplication::desktop()->winId());

    update();
}

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter;

    if( !m_pmap.isNull() )
    {
        painter.begin(this);
        painter.drawPixmap(0, 0, width(), height(), m_pmap);
        painter.end();
    }
}

Widget::~Widget()
{
    
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值