美文网首页
QT:截取图片矩形框线内容

QT:截取图片矩形框线内容

作者: 擎烛而走_b2ce | 来源:发表于2018-06-03 11:02 被阅读0次

    定位截图

    • 说明
      给出利用QImage打开图片,并设置可以任意缩放、平移功能条件下,根据绘制窗口坐标定位矩形框线,截取框线选中内容的实现。

    • 核心算法

    1. 绘制窗口的位置和尺寸是始终固定不变,将其看作是世界坐标系

    2. 图片显示在绘制窗口的子部件QLabel类型成员上,相当于绘制坐标系。图片的移动其实是该QLabel类型成员的移动。

    3. 最终在绘制窗口内显示的图片,是用一个临时Qimage类型变量,储存在原图的基础上进行缩放后的图片,然后将这个临时变量增加到QLabel成员上,并将QLabel成员的大小resize为临时QImage成员的大小,最后平移QLabel成员至绘制窗口中心。

    4.经过以上描述,可知最后绘制在屏幕的图片其实是在原图基础上缩放后的图片,并经过QLabel平移呈现的。如果在绘制窗口上定位,得到的坐标其实是缩放和平移后的坐标,如果想在原图上截取定位框内的图片,需要对定位参数进行反变换,即将定位参数中的起点坐标反向平移QLabel的平移的距离,然后再将起点坐标、长和宽反向缩放图片缩放倍数(因为当前绘制坐标系显示的图片是经过先缩放后平移得到的,所以反变换应先平移后缩放),就可以得到原图上的起点坐标、长和宽。

    5.完成上述操作后,得到原图上的定位参数,因为平移、缩放的系数都是小数,所得到的定位参数一般不是整数,而提取原图像素的下标应为整数, 所以应该将定位参数取整,然后判断是否越界,如果没发生越界再提取像素点。

    • 源代码
    //框线绘制
    void THM_CT::interceptImageFrame()
    {
        interceptDialog* interceptD = new interceptDialog(this);
        interceptD->exec();
        m_interceptWidth = interceptD->width;
        m_interceptHeight = interceptD->height;
        m_interceptX = interceptD->x;
        m_interceptY = interceptD->y;
        m_interceptPattern = interceptD->pattern;
        if (m_interceptPattern == false) return;
        if (m_interceptX < 0 || m_interceptX > m_originalImage.width()) return;
        if (m_interceptY < 0 || m_interceptY > m_originalImage.height()) return;
        if (m_interceptWidth < 0 || m_interceptWidth > m_originalImage.width()) return;
        if (m_interceptHeight < 0 || m_interceptHeight > m_originalImage.height()) return;
        m_showFrameBoolValue = true;
        update();
    }
    //截图
    void THM_CT::interceptImage()
    {
        if (m_interceptPattern == false) return;
    //起点坐标反变换(先平移、后缩放)
        int begin_i = (m_interceptX - (m_showImageLabel->pos().x())) / m_currentIndex;
        int begin_j = (m_interceptY - (m_showImageLabel->pos().y()))/ m_currentIndex;
    //框线尺寸反变换(缩放)
        int wid = m_interceptWidth / m_currentIndex;
        int hei = m_interceptHeight / m_currentIndex;
        int max_i = begin_i + wid;
        int max_j = begin_j + hei;
        //为了确保double转int后不越界
        if (max_i - 1 > m_originalImage.width()) {
            max_i = max_i - 1;
        }
        if (max_j - 1 > m_originalImage.height()) {
            max_j = max_j - 1;
        }
        QImage imgTmp(wid, hei, QImage::Format_RGB16);
        for (int i = begin_i; i < max_i; i++) {
            for (int j = begin_j; j < max_j; j++) {
                if (i >= m_originalImage.width() || j >= m_originalImage.height()) {
                    QMessageBox::warning(this, tr("warning"), tr("Width or height of intercept frame out of range."));
                    return;
                }
                QRgb color = m_originalImage.pixel(i, j);
                imgTmp.setPixel(i - begin_i, j - begin_j, color);
            }
        }
        imgTmp = imgTmp.scaled(m_interceptWidth, m_interceptHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        m_moveX = 0;
        m_moveY = 0;
        m_currentIndex = 1;
        m_currentImage = imgTmp;
        m_originalImage = m_currentImage;
        //取消边框显示
        m_showImageIncrept->clear();
        m_showFrameBoolValue = false;
        //显示截屏后的结果
        updateImage();
    
    }
    

    相关文章

      网友评论

          本文标题:QT:截取图片矩形框线内容

          本文链接:https://www.haomeiwen.com/subject/aqqjsftx.html