为了实现图片的加载和显示,本文主要将使用到Qt中的几个类,分别是:
QImage,这是Qt实现的一个存储图片信息的类,支持大部分的图片格式,支持像素操作,后续所有的图像处理算法都将在这个类的基础上进行操作;
QWidget,将通过继承的方式实现一个自定义的Widget,用于显示图片,缩放等功能;
QPainter,该类将用于QWidget中绘制图片。
图片的加载,这里通过一个打开文件对话框供用户选择图片
void MainWindow::loadImage()
{
clearOperations();
filedir = QFileDialog::getOpenFileName(this, tr("Open File"),
"C:/Users/Aaron/Pictures/standord test/",
tr("Images (*.png *.xpm *.jpg *.tiff *.bmp)"));
if (filedir.isNull()||filedir == "")
{
return;
}
fileName = filedir;
ori_img = new QImage;
ori_img->load(fileName);
//ui.label_1->setPixmap(QPixmap::fromImage((ori_img->scaled(ui.label_1->width(),ui.label_1->height(),Qt::KeepAspectRatio))));
ui.widget_1->setImage(ori_img);
gray_img = IPFbyCJY::Processer::rgb2gray(ori_img);
//ui.label_2->setPixmap(QPixmap::fromImage((gray_img->scaled(ui.label_2->width(),ui.label_2->height(),Qt::KeepAspectRatio))));
ui.widget_2->setImage(gray_img);
showHistogram();
fileload = true;
ui.statusBar->showMessage("Image load");
}
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
enum MouseDown{Left,Mid,Right,No};
class ImageWidget :
public QWidget
{
Q_OBJECT
public:
ImageWidget(QWidget *parent);
~ImageWidget();
void setImage(QImage* img)
{
mp_img = img;
isImageLoad = true;
update();
}
void clear()
{
if(isImageLoad)
{
isImageLoad = false;
//delete mp_img;
mp_img = NULL;
update();
}
}
void iniActions();
void wheelEvent(QWheelEvent *e);
void mouseMoveEvent(QMouseEvent * e);
void mousePressEvent(QMouseEvent * e);
void paintEvent(QPaintEvent *e);
void contextMenuEvent(QContextMenuEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
public slots:
void resetPos();
void zoomout();
void zoomin();
void translate(int x,int y);
void save();
void con_dia();
signals:
void sig_condional_dia(int x,int y);
private:
QImage *mp_img;
float scalex;
float scaley;
int xtranslate;
int ytranslate;
int mousePosX;
int mousePosY;
bool isImageLoad;
MouseDown mouse;
QAction* mActionResetPos;
QAction* mActionSave;
QAction* conditionDialation;
QMenu* mMenu;
bool maxmum;
//QPoint mospos;
public:
int widgetid;
};
图片显示,设置图片的缩放比例以及绘制的起点,使用QPainter绘制图片:
void ImageWidget::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setBrush(QBrush(QColor(121,121,121)));
painter.drawRect(0,0,this->width(),this->height());
if(!isImageLoad)
return;
painter.drawImage(QPoint(xtranslate,ytranslate),mp_img->scaled(this->width()*scalex,this->height()*scaley,Qt::KeepAspectRatio));
}
void ImageWidget::mouseMoveEvent(QMouseEvent *e)
{
if(mouse == Mid)
{
translate(e->x() - mousePosX,e->y() - mousePosY);
}
update();
}
void ImageWidget::translate(int x,int y)
{
xtranslate = x;
ytranslate = y;
update();
}
缩放类似,根据鼠标滚轮调节图片的缩放比例,重绘窗口就可以实现鼠标中间对图片进行缩放
void ImageWidget::zoomout()
{
if(scalex<=100&&scaley<=100)
{
scalex *= 1.2;
scaley *= 1.2;
}
update();
}
void ImageWidget::zoomin()
{
if(scalex>=0.01&&scaley>=0.01)
{
scalex *= 1/1.2;
scaley *= 1/1.2;
}
update();
}
鼠标事件函数重载
void ImageWidget::wheelEvent(QWheelEvent *e)
{
int numDegrees = e->delta();
if(numDegrees > 0)
{
zoomout();
}
if(numDegrees < 0)
{
zoomin();
}
update();
}
void ImageWidget::iniActions()
{
mMenu = new QMenu();
mActionResetPos = mMenu->addAction(tr("reset pos"));
mActionSave = mMenu->addAction(tr("save picture"));
connect(mActionResetPos,SIGNAL(triggered()),this,SLOT(resetPos()));
connect(mActionSave,SIGNAL(triggered()),this,SLOT(save()));
if(widgetid == 3)
{
conditionDialation = mMenu->addAction(tr("Conditionnal dilation"));
connect(conditionDialation,SIGNAL(triggered()),this,SLOT(con_dia()));
}
}
主要添加了重设图片位置、保存图片两个菜单,未来也可以把其他的图片处理的操作都加到右键菜单中。由于3号窗口为右下角的窗口用来显示图片处理结果,这里多加一个操作为conditionDialation,主要用来提取图像中的某个区域,需要鼠标指定位置,这里加在右键菜单中,具体实现以后详述。
右键菜单触发,重载QWidget的右键菜单事件
void ImageWidget::contextMenuEvent(QContextMenuEvent *e)
{
mMenu->exec(QCursor::pos());
//mousePosX = QCursor::pos().x();
//mousePosY = QCursor::pos().y();
}
void ImageWidget::save()
{
if(isImageLoad)
{
QString filename = QFileDialog::getSaveFileName(this, tr("Open File"),
"C:/Users/Aaron/Pictures/",
tr("Images (*.png *.xpm *.jpg *.tiff *.bmp)"));
mp_img->save(filename);
}
}
至此,一个可以显示、缩放、平移以及保存图片的Qt窗口就实现了
运行效果如图