diff --git a/PDFReader.cpp b/PDFReader.cpp new file mode 100644 index 0000000..6a8375f --- /dev/null +++ b/PDFReader.cpp @@ -0,0 +1,219 @@ +#include "PDFReader.h" // 引入 PDFReader 头文件 +#include // 处理字符串流 +#include // 使用正则表达式 +#include // 迭代器支持 +#include // 使用动态数组 +#include // OpenGL 用于渲染 PDF +#include // 处理 C 风格字符串 + +// 构造函数: 打开 PDF 文件 +PDFReader::PDFReader(const std::string& filepath) { + // 以二进制模式打开文件 + file.open(filepath, std::ios::binary); + + // 检查文件是否成功打开 + if (!file) { + // 输出错误信息 + std::cerr << "无法打开 PDF 文件: " << filepath << std::endl; + } +} + +// 析构函数: 关闭 PDF 文件 +PDFReader::~PDFReader() { + // 检查文件是否仍然打开 + if (file.is_open()) { + + // 关闭文件 + file.close(); + } +} + +// 解析 JPEG (DCTDecode) 图片 +void PDFReader::extractImages() { + // 如果文件未打开,直接返回 + if (!file.is_open()) return; + + // 将文件指针移动到文件开头 + file.seekg(0, std::ios::beg); + + // 存储读取的行数据 + std::string line; + + // 逐行读取 PDF 文件内容 + while (std::getline(file, line)) { + // 检测 JPEG 图片标识符 + if (line.find("/DCTDecode") != std::string::npos) { + // 输出发现信息 + std::cout << "发现 JPEG (DCTDecode) 图片" << std::endl; + + // 存储 JPEG 图片的二进制数据 + std::vector imageData; + // 缓冲区用于存储文件数据 + char buffer[1024]; + // 逐块读取文件 + while (file.read(buffer, sizeof(buffer))) { + // 将数据存入 imageData + imageData.insert(imageData.end(), buffer, buffer + file.gcount()); + } + + // 使用 libjpeg 解析 JPEG 图片 + struct jpeg_decompress_struct cinfo; // JPEG 解压缩结构体 + + // JPEG 错误管理 + struct jpeg_error_mgr jerr; + + // 绑定错误管理器 + cinfo.err = jpeg_std_error(&jerr); + + // 初始化 JPEG 解压缩对象 + jpeg_create_decompress(&cinfo); + + // 设定解码数据来源 + jpeg_mem_src(&cinfo, imageData.data(), imageData.size()); + // 读取 JPEG 头部信息 + jpeg_read_header(&cinfo, TRUE); + // 开始解压 + jpeg_start_decompress(&cinfo); + + // 输出图片尺寸 + std::cout << "JPEG 图片尺寸: " << cinfo.output_width << "x" << cinfo.output_height << std::endl; + + // 结束解压 + jpeg_finish_decompress(&cinfo); + // 释放资源 + jpeg_destroy_decompress(&cinfo); + } + } +} + +// 解析 FlateDecode (压缩流) +void PDFReader::parseFlateDecode() { + // 如果文件未打开,直接返回 + if (!file.is_open()) return; + + // 存储压缩数据 + std::vector compressedData; + // 存储读取的行数据 + std::string line; + + // 将文件指针移动到文件开头 + file.seekg(0, std::ios::beg); + // 逐行读取 PDF 文件内容 + while (std::getline(file, line)) { + // 检测 FlateDecode 标识符 + if (line.find("/FlateDecode") != std::string::npos) { + // 输出发现信息 + std::cout << "发现 FlateDecode (压缩流)" << std::endl; + + // 缓冲区用于存储压缩数据 + char buffer[1024]; + // 逐块读取文件 + while (file.read(buffer, sizeof(buffer))) { + // 存入 compressedData + compressedData.insert(compressedData.end(), buffer, buffer + file.gcount()); + } + + // 使用 zlib 解压缩数据 + std::vector uncompressedData(compressedData.size() * 4); // 预分配缓冲区 + + // 初始化 zlib 流结构体 + z_stream strm = { 0 }; + // 设定输入数据 + strm.next_in = compressedData.data(); + // 设定输入数据大小 + strm.avail_in = compressedData.size(); + // 设定输出缓冲区 + strm.next_out = uncompressedData.data(); + // 设定输出缓冲区大小 + strm.avail_out = uncompressedData.size(); + + // 初始化解压 + inflateInit(&strm); + // 执行解压 + inflate(&strm, Z_FINISH); + // 结束解压 + inflateEnd(&strm); + + + // 输出解压后大小 + std::cout << "解压后数据大小: " << strm.total_out << " 字节" << std::endl; + } + } +} + +// 解析 PDF 表格 +void PDFReader::parseTables() { + + // 如果文件未打开,直接返回 + if (!file.is_open()) return; + + // 存储读取的行数据 + std::string line; + // 逐行读取 PDF 文件内容 + while (std::getline(file, line)) { + // 检测表格标识符 + if (line.find("/Table") != std::string::npos) { + // 输出发现信息 + std::cout << "发现 PDF 表格" << std::endl; + + // 存储表格数据 + std::vector> tableData; + // 读取表格内容 + while (std::getline(file, line) && line.find("endtable") == std::string::npos) { + // 存储当前行数据 + std::vector row; + // 使用字符串流分割数据 + std::stringstream ss(line); + // 存储单元格数据 + std::string cell; + + + // 以空格分割单元格 + while (std::getline(ss, cell, ' ')) { + // 存入行数据 + row.push_back(cell); + } + // 存入表格数据 + tableData.push_back(row); + } + + + // 输出表格行数 + std::cout << "表格数据解析完成,共 " << tableData.size() << " 行" << std::endl; + } + } +} + +// OpenGL 渲染 PDF 页面 +display() { + // 清空缓冲区 + glClear(GL_COLOR_BUFFER_BIT); + // 设置颜色(红色) + glColor3f(1.0, 0.0, 0.0); + + // 开始绘制四边形 + glBegin(GL_QUADS); + // 左下角 + glVertex2f(-0.5f, -0.5f); + // 右下角 + glVertex2f(0.5f, -0.5f); + // 右上角 + glVertex2f(0.5f, 0.5f); + // 左上角 + glVertex2f(-0.5f, 0.5f); + + glEnd(); // 结束绘制 + + glFlush(); // 刷新显示 +} + +void PDFReader::renderPDF() { + int argc = 1; + char* argv[1] = { (char*)"PDFRenderer" }; + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE); + glutInitWindowSize(500, 500); + glutCreateWindow("PDF 页面渲染"); + glutDisplayFunc(display); + glutMainLoop(); +}