要求:从本地文件读取一幅图像,在界面左侧展示适合窗口宽度的缩放图,通过鼠标选取左侧图像中的部分区域,在界面右侧显示截取后的图像(按照图像实际像素显示,不做缩放)。左侧图像展示区域无需滚动条,右侧图像如果图像大于窗口则展示滚动条。
效果展示:
功能介绍:鼠标可框选图片可并调整框大小 ,点击cut进行截图,点击repaint重新绘制。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QProgressBar>
#include <QImage>
#include <QDialog>
#include <QSlider>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QResizeEvent>
#include <QTabWidget>
#include <QScrollArea>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QPushButton *pb_open = nullptr;
QPushButton *pb_save = nullptr;
QPushButton *pb_cut = nullptr;
QPushButton *pb_repaint = nullptr;
QLineEdit *le_file = nullptr;
QLabel *lb_be = nullptr;
QLabel *lb_af = nullptr;
QImage im_in;
QImage im_out;
QScrollArea *sa = nullptr;
int nowX;
int nowY;
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
//是否需要移动
bool isMovex1 = false;
bool isMovex2 = false;
bool isMovey1 = false;
bool isMovey2 = false;
bool isstart = false;
void ini_ui();
void show_im(QString);
void cut();
bool eventFilter(QObject *obj, QEvent *event);
void paint();
//void resizeEvent(QResizeEvent *event);
};
#endif // WIDGET_H
ui布局
void Widget::ini_ui()
{
setWindowTitle("Screenshot Tool");
setWindowIcon(QIcon("./icon/icon6.png"));
pb_open = new QPushButton("open",this);
pb_save = new QPushButton("save",this);
pb_cut = new QPushButton("cut",this);
pb_repaint = new QPushButton("repaint",this);
le_file = new QLineEdit(this);
le_file->setReadOnly(true);
lb_be = new QLabel("Original",this);
lb_be->setMinimumHeight(400);
lb_be->setMinimumWidth(400);
lb_be->installEventFilter(this);
sa = new QScrollArea(this);
sa->setMinimumHeight(400);
sa->setMinimumWidth(400);
QHBoxLayout *hl_1 = new QHBoxLayout();
hl_1->addWidget(pb_open);
hl_1->addWidget(le_file);
hl_1->addWidget(pb_save);
QHBoxLayout *hl_2 = new QHBoxLayout();
hl_2->addWidget(lb_be);
hl_2->addWidget(sa);
QHBoxLayout *hl_3 = new QHBoxLayout();
hl_3->addWidget(pb_repaint);
hl_3->addWidget(pb_cut);
QVBoxLayout *vl = new QVBoxLayout();
vl->addLayout(hl_1);
vl->addLayout(hl_2);
vl->addLayout(hl_3);
this->setLayout(vl);
connect(pb_open,&QPushButton::clicked,[=]()
{
QString filename;
filename = QFileDialog::getOpenFileName(
this,
"打开",
"./",
"Image Files (*.png *.jpg *.bmp)");
le_file->setText(filename);
show_im(filename);
x1=0;x2=0;y1=0;y2=0;
});
connect(pb_save,&QPushButton::clicked,[=](){
im_out.save("./out.jpg");
});
connect(pb_cut,&QPushButton::clicked,[=](){
cut();
});
connect(pb_repaint,&QPushButton::clicked,[=](){
x1=0;x2=0;y1=0;y2=0;
});
QFile file(":/QSS/myQss.qss");
file.open(QFile::ReadOnly);
QString styleSheet = tr(file.readAll());
this->setStyleSheet(styleSheet);
file.close();
}
事件过滤器
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj == lb_be)
{
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
QPoint pos = QCursor::pos();
QPoint pos2 = lb_be->mapFromGlobal(pos);
nowX = pos2.x();
nowY = pos2.y();
if(x1==0&&x2==0&&y1==0&&y2==0)
{
isstart = true;
x1 = pos2.x();
y1 = pos2.y();
return true;
}
if(nowY == y1 || nowY == y1 + 1 || nowY == y1 - 1 || nowY == y1 - 2 || nowY == y1 + 2 )
isMovey1 = true;
else if(nowY == y2 || nowY == y2 + 1 || nowY == y2 - 1 || nowY == y2 - 2 || nowY == y2 + 2)
isMovey2 = true;
else if(nowX == x1 || nowX == x1 - 1 || nowX == x1 + 1 || nowX == x1 - 2 || nowY == x1 + 2)
isMovex1 = true;
else if(nowX == x2 || nowX == x2 - 1 || nowX == x2 + 1 || nowX == x2 - 2 || nowX == x2 + 2)
isMovex2 = true;
return true;
}
else return false;
}
else if(event->type() == QEvent::MouseMove)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->buttons() == Qt::LeftButton)
{
QPoint pos = QCursor::pos();
QPoint pos2 = lb_be->mapFromGlobal(pos);
if(isstart == true)
{
x2 = pos2.x();
y2 = pos2.y();
}
else if(isMovey1 == true)
{
y1 = pos2.y();
}
else if(isMovey2 == true)
{
y2 = pos2.y();
}
else if(isMovex1 == true)
{
x1 = pos2.x();
}
else if(isMovex2 == true)
{
x2 = pos2.x();
}
paint();
return true;
}
else return false;
}
else if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
QPoint pos = QCursor::pos();
QPoint pos2 = lb_be->mapFromGlobal(pos);
if(isMovex1 == true)
{
x1 = pos2.x();
isMovex1 = false;
}
else if(isMovey1 == true)
{
y1 = pos2.y();
isMovey1 = false;
}
else if(isMovex2 == true)
{
x2 = pos2.x();
isMovex2 = false;
}
else if(isMovey2 == true)
{
y2 = pos2.y();
isMovey2 = false;
}
else if(isstart == true)
{
x2 = pos2.x();
y2 = pos2.y();
isstart = false;
}
paint();
qDebug()<<x1<<','<<y1<<' '<<x2<<','<<y2;
return true;
}
else return false;
}
else return false;
}
else return QWidget::eventFilter(obj, event);
}
绘制截图框函数
void Widget::paint()
{
QPainter painter;
QImage tempImg = im_in;
double n;
painter.begin(&tempImg);
painter.setPen(QPen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap));
if(tempImg.width()>tempImg.height())
{
n = 1.0*tempImg.width() / lb_be->width();//>=1
if(x1<0)x1=0;
else if(x1>=lb_be->width())x1=lb_be->width();
if(x2<0)x2=0;
else if(x2>=lb_be->width())x2=lb_be->width();
if(y1<0.5*(lb_be->height()-tempImg.height()/n))
y1=0.5*(lb_be->height()-tempImg.height()/n)+1;
else if(y1>=lb_be->height()-(0.5*(lb_be->height()-tempImg.height()/n)))
y1=lb_be->height()-(0.5*(lb_be->height()-tempImg.height()/n))+1;
if(y2<0.5*(lb_be->height()-tempImg.height()/n))
y2=0.5*(lb_be->height()-tempImg.height()/n)+1;
else if(y2>=lb_be->height()-(0.5*(lb_be->height()-tempImg.height()/n)))
y2=lb_be->height()-(0.5*(lb_be->height()-tempImg.height()/n))+1;
painter.drawRect(x1*n,(y1-0.5*(lb_be->height()-tempImg.height()/n))*n, (x2 - x1)*n, (y2 - y1)*n);
}
else
{
n = 1.0*tempImg.height() / lb_be->height();
if(y1<0)y1=0;
else if(y1>=lb_be->height())y1=lb_be->height();
if(y2<0)y2=0;
else if(y2>=lb_be->height())y2=lb_be->height();
if(x1<0.5*(lb_be->width()-tempImg.width()/n))
x1=0.5*(lb_be->width()-tempImg.width()/n)+1;
else if(x1>=lb_be->width()-(0.5*(lb_be->width()-tempImg.width()/n)))
x1=lb_be->width()-(0.5*(lb_be->width()-tempImg.width()/n))+1;
if(x2<0.5*(lb_be->width()-tempImg.width()/n))
x2=0.5*(lb_be->width()-tempImg.width()/n)+1;
else if(x2>=lb_be->width()-(0.5*(lb_be->width()-tempImg.width()/n)))
x2=lb_be->width()-(0.5*(lb_be->width()-tempImg.width()/n))+1;
painter.drawRect((x1-0.5*(lb_be->width()-tempImg.width()/n))*n,y1*n , (x2 - x1)*n, (y2 - y1)*n);
}
painter.end();
QPixmap pix;
pix = QPixmap::fromImage(tempImg);
pix = pix.scaled(lb_be->size(),Qt::KeepAspectRatio);
lb_be->setPixmap(pix);
lb_be->setAlignment(Qt::AlignCenter);
}
裁剪函数
void Widget::cut()
{
QImage tempImg = im_in;
lb_af = new QLabel(this);
if(x1>x2)
{
int temp = x1;
x1=x2;
x2=temp;
}
if(y1>y2)
{
int temp = y1;
y1=y2;
y2=temp;
}
double n;
if(tempImg.width()>tempImg.height())
{
n = 1.0*tempImg.width() / lb_be->width();
im_out=tempImg.copy(x1*n, (y1-0.5*(lb_be->height()-tempImg.height()/n))*n, (x2 - x1)*n, (y2 - y1)*n);
}
else
{
n = 1.0*tempImg.height() / lb_be->height();
im_out=tempImg.copy((x1-0.5*(lb_be->width()-tempImg.width()/n))*n,y1*n , (x2 - x1)*n, (y2 - y1)*n);
}
lb_af->resize(im_out.width(),im_out.height());
QPixmap pix;
pix = QPixmap::fromImage(im_out);
lb_af->setPixmap(pix);
sa->setAlignment(Qt::AlignCenter);
sa->setWidgetResizable(false);
sa->setWidget(lb_af);
}