首页
/ ScreenCapture截图功能实现

ScreenCapture截图功能实现

2026-02-04 05:06:43作者:柯茵沙

ScreenCapture 提供了强大的区域截图、全屏截图、长截图(滚动截图)以及截图保存与压缩功能。这些功能通过 WinFullWinLong 等类实现,支持用户交互、图像拼接、压缩优化等技术。

区域截图与全屏截图的实现

ScreenCapture 提供了强大的区域截图和全屏截图功能,这些功能通过 WinFullWinLong 类实现。以下将详细介绍其实现细节和技术要点。

1. 全屏截图 (WinFull)

全屏截图功能由 WinFull 类负责,该类继承自 WinBase,提供了完整的屏幕捕获能力。以下是其核心实现:

类定义 (WinFull.h)

class WinFull : public WinBase {
public:
    WinFull(QWidget* parent = nullptr);
    ~WinFull();
};

实现流程

  1. 初始化:构造函数中设置窗口属性,确保捕获整个屏幕。
  2. 捕获屏幕:通过 Qt 的 QScreen 类获取当前屏幕的图像数据。
  3. 显示与交互:将捕获的图像显示在窗口中,并提供标注工具。

流程图

flowchart TD
    A[启动全屏截图] --> B[初始化窗口]
    B --> C[捕获屏幕图像]
    C --> D[显示图像并提供标注工具]
    D --> E[保存或复制到剪贴板]

2. 区域截图 (WinLong)

区域截图功能由 WinLong 类实现,支持用户自定义截取屏幕的任意区域。以下是其核心实现:

类定义 (WinLong.h)

class WinLong : public WinBase {
public:
    WinLong(QWidget *parent = nullptr);
    ~WinLong();
private:
    WinLongTip* winLongTip;
};

实现流程

  1. 初始化:构造函数中设置窗口属性,并初始化提示窗口 (WinLongTip)。
  2. 用户交互:用户通过鼠标拖拽选择截取区域。
  3. 捕获区域:根据用户选择的区域坐标,截取屏幕图像。
  4. 显示与交互:将捕获的图像显示在窗口中,并提供标注工具。

流程图

flowchart TD
    A[启动区域截图] --> B[初始化窗口和提示]
    B --> C[用户拖拽选择区域]
    C --> D[捕获区域图像]
    D --> E[显示图像并提供标注工具]
    E --> F[保存或复制到剪贴板]

3. 技术要点对比

功能 实现类 核心方法 交互方式
全屏截图 WinFull QScreen::grabWindow 直接捕获整个屏幕
区域截图 WinLong QScreen::grabWindow + 坐标 用户拖拽选择区域

4. 代码示例

以下是一个简单的示例,展示如何调用 WinFullWinLong 实现截图功能:

// 全屏截图示例
WinFull* fullScreen = new WinFull();
fullScreen->show();

// 区域截图示例
WinLong* regionScreen = new WinLong();
regionScreen->show();

5. 性能优化

  • 图像压缩:通过 --comp 参数控制图像质量和缩放比例,减少文件大小。
  • 低资源占用:使用高效的 Qt 图像处理接口,确保低 CPU 和内存消耗。

通过以上实现,ScreenCapture 提供了高效且灵活的区域截图和全屏截图功能,满足不同场景下的需求。

长截图(滚动截图)的实现

长截图(滚动截图)是一种常见的屏幕截图功能,特别适用于需要截取超出屏幕可视区域的内容,例如网页、文档或应用程序的滚动视图。在ScreenCapture项目中,这一功能通过WinLong类实现,结合了多线程、图像处理和用户交互技术。以下将详细介绍其实现细节。

核心类与功能

长截图功能主要由WinLong类实现,其继承自WinBase,并包含以下核心组件:

  • CutMask:用于定义截图区域。
  • WinLongTip:提示用户操作的浮动窗口。
  • ToolLong:提供截图工具按钮。
  • QTimer:控制截图步骤的执行频率。

以下是WinLong类的关键方法及其作用:

方法名 作用描述
startCap 开始长截图流程,初始化截图区域和第一帧图像。
capStep 执行单次截图步骤,捕获当前帧并与前一帧对比,拼接图像。
timerFunc 定时触发滚动操作,模拟鼠标滚轮事件。
initTool 初始化截图工具按钮,提供用户交互界面。
initArea 根据用户选择的区域计算实际截图坐标和尺寸。

实现流程

长截图的实现流程可以分为以下几个步骤:

  1. 用户选择截图区域
    用户通过鼠标拖动选择需要截取的区域,CutMask类负责绘制和更新选择框。

  2. 初始化截图
    调用startCap方法,捕获第一帧图像并初始化相关参数:

    img1 = Util::printScreen(areaX, areaY, areaW, areaH);
    imgResult = img1;
    
  3. 滚动与截图
    通过定时器QTimer触发timerFunc方法,模拟鼠标滚轮事件滚动页面。随后调用capStep方法捕获新帧并拼接图像:

    auto img2 = Util::printScreen(areaX, areaY, areaW, areaH);
    QImage imgResultNew = QImage(imgResult.width(), paintStart + (img2.height() - startY), QImage::Format_ARGB32);
    
  4. 图像拼接
    通过对比前后两帧图像的差异区域,找到最佳拼接点,将新帧追加到结果图像中:

    auto y = findMostSimilarRegionParallel(img11, img22);
    QPainter p(&imgResultNew);
    p.drawImage(0, 0, imgResult);
    p.drawImage(0, paintStart, img3);
    
  5. 终止条件
    当检测到页面已滚动到底部(dismissTime > 2)或结果图像过长(imgResult.height() > 20000)时,停止截图流程。

关键技术点

  • 图像对比算法:通过逐像素对比前后两帧图像,找到差异区域并确定拼接位置。
  • 多线程处理:使用QTimer和异步操作确保截图流程的流畅性。
  • 用户交互:通过ToolLongWinLongTip提供友好的操作提示。

流程图

flowchart TD
    A[用户选择截图区域] --> B[初始化截图]
    B --> C[捕获第一帧图像]
    C --> D[启动定时器]
    D --> E[模拟滚轮事件]
    E --> F[捕获新帧]
    F --> G{是否可拼接?}
    G -->|是| H[拼接图像]
    G -->|否| I[终止截图]
    H --> E

通过以上实现,ScreenCapture项目为用户提供了高效、稳定的长截图功能,适用于多种场景需求。

截图保存与压缩功能实现

ScreenCapture 提供了强大的截图保存与压缩功能,支持多种格式和灵活的压缩选项。以下将详细介绍其实现细节和使用方式。

1. 保存功能实现

截图保存功能主要通过 Util::saveToFile 方法实现,支持以下特性:

  • 文件路径设置:用户可以通过命令行参数 --path 指定保存路径,支持自动生成文件名或自定义文件名。
  • 格式支持:目前仅支持 PNG 格式。
  • 压缩选项:通过 --comp 参数控制压缩质量和缩放比例。

代码示例

bool Util::saveToFile(const QImage& img) {
    auto savePath = App::getSavePath();
    auto [compressQuality, compressSize] = App::getCompressVal();
    if (savePath.toUpper().endsWith(".PNG")) {
        if (compressSize != 100) {
            QImage image = img.scaled(img.width() * compressSize/100, 
                img.height() * compressSize/100,
                Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
            image.save(savePath, "PNG", compressQuality);
        } else {
            img.save(savePath, "PNG", compressQuality);
        }
    }
    return true;
}

流程图

flowchart TD
    A[开始] --> B{检查保存路径}
    B -->|路径为空| C[弹出文件对话框]
    B -->|路径非空| D[检查压缩参数]
    D -->|压缩比例非100%| E[缩放图像]
    D -->|压缩比例为100%| F[直接保存]
    E --> F
    F --> G[保存为PNG]
    G --> H[结束]

2. 压缩功能实现

压缩功能通过 App::getCompressVal 方法获取压缩参数,支持以下选项:

  • 压缩质量:取值范围为 -19,其中 -1 为默认压缩,0 为最小压缩,9 为最大压缩。
  • 缩放比例:取值范围为 1100,表示图像的缩放百分比。

代码示例

std::tuple<int, int> App::getCompressVal() {
    return {compressQuality, compressSize};
}

参数说明

参数名称 取值范围 说明
compressQuality -1 到 9 压缩质量,数字越大压缩越强
compressSize 1 到 100 缩放比例,100 表示不缩放

3. 剪贴板保存功能

截图可以直接保存到剪贴板,通过 Util::imgToClipboard 方法实现。该方法同样支持压缩和缩放功能。

代码示例

void Util::imgToClipboard(const QImage& image) {
    auto [_, compressSize] = App::getCompressVal();
    QImage img;
    if (compressSize != 1.0) {
        img = image.scaled(image.width() * compressSize/100, 
            image.height() * compressSize/100, 
            Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    } else {
        img = image;
    }
    QApplication::clipboard()->setImage(img);
}

流程图

flowchart TD
    A[开始] --> B{检查压缩比例}
    B -->|比例非100%| C[缩放图像]
    B -->|比例为100%| D[直接使用原图]
    C --> E[保存到剪贴板]
    D --> E
    E --> F[结束]

4. 命令行参数示例

以下是一些常用的命令行参数示例:

# 保存到指定路径,压缩质量为6,缩放比例为60%
ScreenCapture.exe --path:"D:\\screenshots" --comp:6,60

# 保存到剪贴板,压缩质量为默认值
ScreenCapture.exe --cap:custom,clipboard

通过以上功能,用户可以灵活地控制截图的保存和压缩行为,满足不同场景的需求。

截图与钉图的交互逻辑

ScreenCapture 的截图与钉图功能是其核心特性之一,通过高效的交互逻辑实现了从截图到钉图的完整流程。以下将详细解析这一交互逻辑的实现方式。

1. 截图到钉图的流程

以下是截图完成后钉图的基本流程:

sequenceDiagram
    participant User
    participant ScreenCapture
    participant WinPin
    participant WinPinBtns

    User->>ScreenCapture: 完成截图
    ScreenCapture->>WinPin: 创建钉图窗口
    WinPin->>WinPinBtns: 初始化控制按钮
    WinPinBtns-->>WinPin: 返回按钮实例
    WinPin-->>ScreenCapture: 显示钉图窗口
    ScreenCapture->>User: 钉图窗口展示

2. 关键类与功能

以下是涉及钉图功能的核心类及其职责:

类名 功能描述
WinPin 钉图窗口的主类,负责显示截图内容并提供交互功能(如缩放、移动)。
WinPinBtns 钉图窗口的控制按钮组,包含保存、关闭等功能按钮,通过信号槽与 WinPin 交互。

3. 交互逻辑实现

3.1 钉图窗口的创建

当用户完成截图后,ScreenCapture 会调用 WinPin 的构造函数创建钉图窗口,并传入截图内容和初始位置:

WinPin(const QPoint& pos, QImage& img, QWidget *parent = nullptr);

3.2 控制按钮的初始化

WinPinBtns 是钉图窗口的控制按钮组,其初始化逻辑如下:

WinPinBtns(QWidget *parent = nullptr);

WinPin 在构造函数中会创建 WinPinBtns 实例,并将其布局到钉图窗口的合适位置。

3.3 按钮事件处理

WinPinBtns 中的按钮通过信号槽机制与 WinPin 交互。例如:

  • 保存按钮:触发保存截图到文件的逻辑。
  • 关闭按钮:关闭钉图窗口并释放资源。

4. 代码示例

以下是一个简化的钉图窗口初始化代码片段:

// WinPin 构造函数片段
WinPin::WinPin(const QPoint& pos, QImage& img, QWidget *parent) : WinBase(parent) {
    // 设置窗口位置和截图内容
    this->move(pos);
    this->setImage(img);

    // 初始化控制按钮
    btns = new WinPinBtns(this);
    btns->move(10, 10); // 按钮位置调整
    connect(btns, &WinPinBtns::saveClicked, this, &WinPin::onSave);
    connect(btns, &WinPinBtns::closeClicked, this, &WinPin::close);
}

5. 交互优化

为了提高用户体验,钉图窗口还支持以下功能:

  • 鼠标滚轮缩放:通过重写 wheelEvent 实现截图内容的动态缩放。
  • 窗口拖拽移动:通过重写 mousePressEventmouseMoveEvent 实现窗口的拖拽功能。

通过以上设计,ScreenCapture 实现了高效且用户友好的截图与钉图交互逻辑。

ScreenCapture 通过模块化设计和高效的技术实现,为用户提供了灵活且强大的截图工具。从区域截图到长截图,再到保存与压缩功能,其交互逻辑和性能优化均体现了高度的实用性和可扩展性。

登录后查看全文
热门项目推荐
相关项目推荐