头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QtGui>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <opencv2/opencv.hpp>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
enum Type {
None = 0,
Amplification ,
Shrink,
Lift,
Right,
Up,
Down,
Move
};
public:
cv::Mat img;
cv::Mat imgchance;
cv::Mat scalingImg(cv::Mat& mat, int INPUT_H, int INPUT_W);
QImage matToImage(const cv::Mat& mat);
QImage imgDst;
private:
Ui::MainWindow *ui;
// QPixmap *pix;
int action; //动作(放大,缩小,移动...)
int pixW; //图片宽
int pixH; //图片高
int lableW; //lable 宽
int lableH; //lable 高
QRect PaintRect; //绘画区域
QLabel label;
float ratio; //比例
QPoint offset; //一次的图片偏移值
QPoint Alloffset; //总偏移
void AddComboItem(QComboBox* cmbo);
bool event(QEvent * event);
void wheelEvent(QWheelEvent* e); //鼠标滑轮事件
private slots:
void paintEvent(QPaintEvent *event);
};
#endif // MAINWINDOW_H
CPP文章来源:https://www.toymoban.com/news/detail-596105.html
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QPushButton>
#include <QApplication>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
Alloffset(0,0)
{
ui->setupUi(this);
ratio= 1.0; //初始化图片缩放比例
action = MainWindow::None;
lableW = pixW = 500;
lableH = pixH = 900;
QString path = "D:/Vscode_Project/Img/H_w.jpg";
img = cv::imread(path.toStdString());
imgchance = scalingImg(img,pixH,pixW);
pixW = imgchance.cols;
pixH = imgchance.rows;
imgDst = matToImage(imgchance);
PaintRect.setRect(ui->label->x()-1,ui->label->y()-1,lableW,lableH);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::event(QEvent * event)
{
static bool press=false;
static QPoint PreDot;
if(event->type() == QEvent::MouseButtonPress )
{
QMouseEvent *mouse = dynamic_cast<QMouseEvent* >(event);
//判断鼠标是否是左键按下,且鼠标位置是否在绘画区域
if(mouse->button()==Qt::LeftButton &&PaintRect.contains(mouse->pos()))
{
press=true;
QApplication::setOverrideCursor(Qt::OpenHandCursor); //设置鼠标样式
PreDot = mouse->pos();
}
}
else if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent *mouse = dynamic_cast<QMouseEvent* >(event);
//判断鼠标是否是左键释放,且之前是在绘画区域
if(mouse->button()==Qt::LeftButton && press )
{
QApplication::setOverrideCursor(Qt::ArrowCursor); //改回鼠标样式
press=false;
}
}
if(event->type() == QEvent::MouseMove) //移动图片
{
if(press)
{
QMouseEvent *mouse = dynamic_cast<QMouseEvent* >(event);
offset.setX(mouse->x() - PreDot.x());
offset.setY(mouse->y() - PreDot.y());
PreDot = mouse->pos();
action = MainWindow::Move;
this->update();
}
}
return QWidget::event(event);
}
void MainWindow::wheelEvent(QWheelEvent* event) //鼠标滑轮事件
{
if (event->delta()>0) { //上滑,缩小
action=MainWindow::Shrink;
this->update();
} else { //下滑,放大
action=MainWindow::Amplification;
this->update();
}
event->accept();
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
int NowW = ratio *pixW;
int NowH = ratio *pixH;
if(action==MainWindow::Amplification) //缩小
{
ratio-=0.1*ratio;
if(ratio<0.18)
ratio = 0.1;
}
else if(action==MainWindow::Shrink) //放大
{
ratio+=0.1*ratio;
if(ratio>4.5)
ratio = 5.000;
}
if(action==MainWindow::Amplification || action==MainWindow::Shrink) //更新图片
{
NowW = ratio *pixW;
NowH = ratio *pixH;
action=MainWindow::None;
imgchance = scalingImg(img,NowH,NowW);
imgDst = matToImage(imgchance);
}
if(action==MainWindow::Move) //移动
{
int offsetx=Alloffset.x()+offset.x();
Alloffset.setX(offsetx);
int offsety=Alloffset.y()+offset.y();
Alloffset.setY(offsety);
action=MainWindow::None;
}
if(abs(Alloffset.x())>=(lableW/2 + NowW/2 -10)) //限制X偏移值
{
if(Alloffset.x()>0)
Alloffset.setX(lableW/2 + NowW/2 -10);
else
Alloffset.setX(-lableW/2 + -NowW/2 +10);
}
if(abs(Alloffset.y())>=(lableH/2 + NowH/2 -10)) //限制Y偏移值
{
if(Alloffset.y()>0)
Alloffset.setY(lableH/2 + NowH/2 -10);
else
Alloffset.setY(-lableH/2 + -NowH/2 +10);
}
int x = lableW/2 + Alloffset.x() -NowW/2;
if(x<0)
x=0;
int y = lableH/2 + Alloffset.y() -NowH/2;
if(y<0)
y=0;
int sx = NowW/2 - lableW/2 - Alloffset.x();
if(sx<0)
sx=0;
int sy = NowH/2 - lableH/2 - Alloffset.y();
if(sy<0)
sy=0;
int w =(NowW - sx)>lableW? lableW : (NowW - sx);
if(w>(lableW-x))
w = lableW-x;
int h =(NowH - sy)>lableH? lableH : (NowH - sy);
if(h>(lableH-y))
h = lableH-y;
qDebug()<<"start w "<<w;
qDebug()<<"start h "<<h;
NowW = ratio *pixW;
NowH = ratio *pixH;
action=MainWindow::None;
imgchance = scalingImg(img,NowH,NowW);
imgDst = matToImage(imgchance);
painter.drawRect(ui->label->x()-1,ui->label->y()-1,lableW,lableH); //画框
painter.drawTiledPixmap(x+ui->label->x(),y+ui->label->y(),w,h,QPixmap::fromImage(imgDst),sx,sy);
qDebug()<<" ";
qDebug()<<"drawTiledPixmap w "<<w;
qDebug()<<"drawTiledPixmap h "<<h;
// qDebug()<<"imgchance w "<<imgchance.cols;
// qDebug()<<"imgchance h "<<imgchance.rows;
}
cv::Mat MainWindow::scalingImg(cv::Mat& mat, int INPUT_H, int INPUT_W)
{
int nh = mat.rows;
int nw = mat.cols;
double divisor;
double m_nh = nh / 1.0 / INPUT_H;
double m_nw = nw / 1.0 / INPUT_W;
divisor = (m_nh > m_nw ? m_nh : m_nw);
cv::Mat image = mat.clone();
cv::Mat image_resize; // 等比例缩放图
//图片要缩:INTER_AREA 图片要放:INTER_CUBIC
if (nh > INPUT_H || nw > INPUT_W)
{
cv::resize(image, image_resize, cv::Size(nw / divisor, nh / divisor), cv::INTER_AREA);
}
else
{
cv::resize(image, image_resize, cv::Size(nw / divisor, nh / divisor), cv::INTER_CUBIC);
}
return image_resize;
}
QImage MainWindow::matToImage(const cv::Mat& mat)
{
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
uchar* pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar* pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if (mat.type() == CV_8UC3)
{
const uchar* pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_BGR888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC4)
{
cv::cvtColor(mat, mat, cv::COLOR_BGRA2RGBA);
const uchar* pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image;
}
else
{
return QImage();
}
}
lable 不是必要的,设置好关键的2个值最重要文章来源地址https://www.toymoban.com/news/detail-596105.html
到了这里,关于qt QPainter 实现图片的缩放和平移的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!