qt QPainter 实现图片的缩放和平移

这篇具有很好参考价值的文章主要介绍了qt QPainter 实现图片的缩放和平移。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

头文件

#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

#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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c++ QT opengl鼠标控制平移、缩放、绕点旋转

    坐标系固定在左下角 坐标系和正方形 一起旋转,但不平移与缩放 鼠标左键平移正方形,右键旋转,滚轮缩放(放大与缩小) 编写绘制正方形与坐标系函数 在OpenGL窗口界面绘制 实现鼠标左键平移移动,右键旋转,滚轮缩放(放大与缩小) 设置正方形的旋转点 ,以及坐标系

    2024年02月06日
    浏览(37)
  • opencv006图像处理之仿射变换(旋转,缩放,平移)

    空间变换中的仿射变换对应着五种变换,平移,缩放,旋转,翻转,错切。而这五种变化由原图像转变到变换图像的过程,可以用仿射变换矩阵进行描述。而这个变换过程可以用一个2*3的矩阵与原图进行相乘得到。关键就是这个矩阵M:  平移,旋转   透视 M: 变换矩阵 desi

    2024年01月21日
    浏览(52)
  • 【QT开发(5)】0919-QT里面新增ui类,新增使用opencv读取图片的普通类,在ui类中显示图片

    1、Qt Creator快速入门_第三版__霍亚飞编著 2、《Qt+OpenCV显示图片(Mat转QImage然后显示在QLabel上)》 https://gitee.com/hiyanyx/qt5.14-cpp_-empty_-project/tree/Study2023-section5/ git分支“Study2023-section5” 新增ui类 新增使用opencv读取图片的普通类 为了更加方便,可在QT 中添加普通类,这样会自动生

    2024年02月07日
    浏览(47)
  • QT学习笔记(三)——vs2019+Qt实现打开影像并以鼠标为中心用滚轮控制图片缩放

    之前写了一个博客讲怎么显示一张影像,那个是基于Qpainter的 今天使用QLabel来显示影像,并且用鼠标滚轮控制缩放。 关于图像的打开和显示,主要参考这个博客 关于如何使图片自适应窗口与铺满窗口,可以参考这个博客。 这两个博客出自同一作者,都很详细。 其中按照第二

    2024年02月09日
    浏览(44)
  • Halcon用矩阵实现图像变换(平移,旋转,缩放,镜像等)

    目录 图像变换介绍  用Halcon自带的算子实现图像变换 使用矩阵来实现相关算子的功能 一、平移 二、旋转 三、缩放 四、镜像 完整代码         在halcon中经常会用到图像变换的操作,然后这次作业是用矩阵来实现相关算子的功能,学到了挺多的所以就记录下来方便复习。

    2024年04月17日
    浏览(42)
  • python实现两函数通过缩放,平移和旋转进行完美拟合

    前几天在工作的时候接到了一个需求,希望将不同坐标系,不同角度的两条不规则曲线,并且组成该曲线的点集数量不一致,需求是希望那个可以通过算法的平移和旋转搞到一个概念里最贴合,拟合态进行比较。 这是初步将两组数据画到图里的情况,和背景需求是一致的。其

    2024年02月15日
    浏览(36)
  • Android中矩阵Matrix实现平移,旋转,缩放和翻转的用法详细介绍

    一,矩阵Matrix的数学原理 矩阵的数学原理涉及到矩阵的运算和变换,是高等代数学中的重要概念。在图形变换中,矩阵起到关键作用,通过矩阵的变换可以改变图形的位置、形状和大小。矩阵的运算是数值分析领域的重要问题,对矩阵进行分解和简化可以简化计算过程。对于

    2024年01月22日
    浏览(54)
  • qt+opencv实现图片编辑器

    借助QLabel容器,进行显示图片作为背景,然后重写QLabel类实现矩形,直线和圆形的实现。opencv板块直接实现相关图片操作。 打开图片 裁切 改变亮度和对比度 顺时针旋转和逆时针旋转 重写的QLabel

    2024年02月16日
    浏览(46)
  • OpenCV对图片进行缩放处理

    在下面的代码中,我会为你优化和解释这段程序:

    2024年02月13日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包