go-fitz库介绍及使用go-fitz将PDF转换为图片

118 阅读5分钟

go-fitz 库介绍:Go 语言下的多格式文档处理工具

go-fitz 是一个基于 Go 语言的开源项目,核心是对轻量级文档处理库 MuPDF 的 Fitz 模块进行 Go 语言封装,让开发者能在 Go 项目中便捷使用 MuPDF 的文档处理能力。

一、核心能力与支持的文档格式

  • 多格式解析:支持 PDF、EPUB、MOBI、DOCX、XLSX、PPTX 等多种文档格式。
  • 内容提取与转换:可从文档中提取页面内容,并输出为图像(JPEG、PNG、TIFF 等)、纯文本(TXT)、HTML 或 SVG 格式。

二、关键特性

  1. 纯 Go 与 CGO 双实现:除了依赖 CGO 调用 MuPDF 原生 C 库的方式,还提供纯 Go 实现选项,能在不支持 CGO 的环境(如部分受限容器、嵌入式场景)中使用。

  2. 灵活的构建与依赖管理:通过 extlibpkgconfigstaticmusl 等构建标签,支持:

    • 链接外部 MuPDF 库;
    • 静态链接 MuPDF(结合 extlib 使用);
    • 适配 musl 编译环境等。
  3. 并发友好:虽然不支持单文档的并发处理(避免文档内部状态冲突),但可同时对多个不同文档进行并发请求,适合批量文档处理场景。

  4. 性能与错误处理优化:近期更新中对大文档处理进行了性能优化,同时改进了错误处理机制,能更清晰地捕获和报告异常。

三、使用与集成

  1. 安装:通过 Go 模块管理工具安装:

    bash

    go get github.com/gen2brain/go-fitz
    
  2. 简单示例(以 PDF 处理为例)

    go

    运行

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/gen2brain/go-fitz"
    )
    
    func main() {
        // 打开 PDF 文档
        doc, err := fitz.New("example.pdf")
        if err != nil {
            fmt.Fprintf(os.Stderr, "打开文档失败: %v\n", err)
            os.Exit(1)
        }
        defer doc.Close()
    
        // 提取文档页数
        pageCount := doc.NumPage()
        fmt.Printf("文档共 %d 页\n", pageCount)
    
        // 提取第 0 页为 PNG 图像
        img, err := doc.Image(0)
        if err != nil {
            fmt.Fprintf(os.Stderr, "提取页面图像失败: %v\n", err)
            os.Exit(1)
        }
        // 结合 image 库可将 img 保存为文件(此处省略具体保存逻辑)
        fmt.Println("页面图像提取成功")
    }
    
  3. 项目结构与核心文件go-fitz 项目结构简洁,核心文件包括:

    • fitz.go:主 API 接口文件,定义 Document 等核心结构体和方法(如 New 打开文档、Image 提取图像)。
    • fitz_cgo.go:CGO 相关代码,负责与 MuPDF C 库交互。
    • fitz_content_types.go:处理文档内容类型的辅助逻辑。
    • examples/:包含转换、提取、生成缩略图等示例代码,快速演示库的用法。

四、依赖与环境要求

  • 底层依赖:需安装 MuPDF 的开发文件(因基于 MuPDF 封装),确保编译时能找到头文件和库文件。

  • CGO 支持:若使用 CGO 版本,需确保环境中 CGO_ENABLED=1(Go 默认启用,但跨平台编译时需注意)。

  • 模块管理:通过 go.mod 管理依赖,典型依赖配置如下:

    go

    运行

    module github.com/gen2brain/go-fitz
    go 1.15
    require github.com/gen2brain/go-fitz v1.23.7
    

五、常见问题与解决方案

  • 错误:undefined: fitz.New:通常是依赖未正确导入或下载。解决方案:

    1. 检查 go.mod 是否包含 go-fitz 依赖;
    2. 执行 go mod tidy 和 go mod download 同步依赖;
    3. 若使用第三方代码托管平台(如 GitCode)的镜像,确保网络可访问并正确配置域名解析。
  • 跨平台编译问题:因涉及 CGO 和 MuPDF 原生库,跨平台编译时需确保目标平台支持 MuPDF,或切换到纯 Go 实现(通过构建标签控制)。

综上,go-fitz 为 Go 开发者提供了轻量、灵活的多格式文档处理能力,适合集成到需要文档解析、内容提取的应用(如文档管理系统、OCR 前置处理、电子书工具等)中。

使用go-fitz将PDF转换为图片

go-fitz是一个Go语言库,它封装了Poppler库的功能,可以将PDF文档转换为图像。以下是详细的使用方法:

package main

import (
	"fmt"
	"image/png"
	"log"
	"os"
	"path/filepath"

	"github.com/gen2brain/go-fitz"
)

// ConvertPdfToPng 将PDF文件的每一页转换为PNG图片
// 参数:
//   - pdfPath: PDF文件路径
//   - outputDir: 输出图片目录
//   - dpi: 转换分辨率(通常150-300之间)
// 返回值:
//   - error: 错误信息
func ConvertPdfToPng(pdfPath, outputDir string, dpi float64) error {
	// 创建PDF文档对象
	doc, err := fitz.New(pdfPath)
	if err != nil {
		return fmt.Errorf("无法打开PDF文件: %v", err)
	}
	// 函数结束时关闭文档,释放资源
	defer doc.Close()

	// 获取PDF总页数
	totalPages := doc.NumPage()
	fmt.Printf("PDF共%d页,开始转换...\n", totalPages)

	// 遍历每一页并转换为图片
	for i := 0; i < totalPages; i++ {
		// 使用ImageDPI方法将PDF页面转换为指定分辨率的图像
		// 第一个参数是页码(从0开始),第二个参数是DPI值
		img, err := doc.ImageDPI(i, dpi)
		if err != nil {
			log.Printf("警告: 转换第%d页失败: %v", i+1, err)
			continue
		}

		// 构造输出文件路径
		outputPath := filepath.Join(outputDir, fmt.Sprintf("page_%03d_%.0fdpi.png", i+1, dpi))
		
		// 创建输出文件
		outFile, err := os.Create(outputPath)
		if err != nil {
			log.Printf("警告: 无法创建文件 '%s': %v", outputPath, err)
			continue
		}
		
		// 将图像编码为PNG格式并写入文件
		if err := png.Encode(outFile, img); err != nil {
			log.Printf("警告: 无法编码PNG文件 '%s': %v", outputPath, err)
			outFile.Close()
			continue
		}
		
		// 关闭文件
		outFile.Close()
		fmt.Printf("第%d页已保存为: %s\n", i+1, outputPath)
	}

	fmt.Println("所有页面转换完成!")
	return nil
}

func main() {
	// 示例使用
	pdfFile := "example.pdf"           // PDF文件路径
	outputDir := "./output"            // 输出目录
	dpi := 150.0                       // 分辨率

	// 确保输出目录存在
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		log.Fatal("无法创建输出目录:", err)
	}

	// 调用转换函数
	if err := ConvertPdfToPng(pdfFile, outputDir, dpi); err != nil {
		log.Fatal("转换失败:", err)
	}
}

这段代码展示了如何使用go-fitz库将PDF的每一页转换为PNG图片。关键点包括:

  1. 使用[fitz.New]创建PDF文档对象
  2. 使用[doc.NumPage()]获取总页数
  3. 使用[doc.ImageDPI()]方法将PDF页面转换为指定分辨率的图像
  4. 使用PNG编码器将图像保存为PNG文件