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

定位截图

  • 说明
    给出利用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:截取图片矩形框线内容)